diff --git a/package-lock.json b/package-lock.json index ec3604b..3735184 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1047,6 +1047,74 @@ "to-fast-properties": "^2.0.0" } }, + "@eslint/eslintrc": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.1.tgz", + "integrity": "sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "espree": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "import-fresh": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -1107,12 +1175,40 @@ "glob-to-regexp": "^0.3.0" } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + } + } + }, "@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "dev": true }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, "@soda/friendly-errors-webpack-plugin": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.1.tgz", @@ -1240,12 +1336,6 @@ "@types/node": "*" } }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true - }, "@types/express": { "version": "4.17.9", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.9.tgz", @@ -1269,6 +1359,12 @@ "@types/range-parser": "*" } }, + "@types/geojson": { + "version": "7946.0.7", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz", + "integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==", + "dev": true + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -1305,6 +1401,15 @@ "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", "dev": true }, + "@types/leaflet": { + "version": "1.5.19", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.5.19.tgz", + "integrity": "sha512-ZAKqfvdU/+KFoCpf8aUba09F8mfSc8R2esq++Cha3E2DgwS5K/I/4eJ+0JylrVHZivgY7PSAeXFv/izP+81/MQ==", + "dev": true, + "requires": { + "@types/geojson": "*" + } + }, "@types/mime": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", @@ -1460,90 +1565,16 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", - "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.8.1.tgz", + "integrity": "sha512-d7LeQ7dbUrIv5YVFNzGgaW3IQKMmnmKFneRWagRlGYOSfLJVaRbj/FrBNOBC1a3tVO+TgNq1GbHvRtg1kwL0FQ==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "2.34.0", + "@typescript-eslint/experimental-utils": "4.8.1", + "@typescript-eslint/scope-manager": "4.8.1", + "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", - "tsutils": "^3.17.1" - }, - "dependencies": { - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - }, - "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "@typescript-eslint/experimental-utils": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", - "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.34.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - } - } - }, - "@typescript-eslint/parser": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", - "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", - "dev": true, - "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.34.0", - "@typescript-eslint/typescript-estree": "2.34.0", - "eslint-visitor-keys": "^1.1.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", - "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", "semver": "^7.3.2", "tsutils": "^3.17.1" }, @@ -1565,6 +1596,221 @@ } } }, + "@typescript-eslint/experimental-utils": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.8.1.tgz", + "integrity": "sha512-WigyLn144R3+lGATXW4nNcDJ9JlTkG8YdBWHkDlN0lC3gUGtDi7Pe3h5GPvFKMcRz8KbZpm9FJV9NTW8CpRHpg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.8.1", + "@typescript-eslint/types": "4.8.1", + "@typescript-eslint/typescript-estree": "4.8.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.8.1.tgz", + "integrity": "sha512-QND8XSVetATHK9y2Ltc/XBl5Ro7Y62YuZKnPEwnNPB8E379fDsvzJ1dMJ46fg/VOmk0hXhatc+GXs5MaXuL5Uw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.8.1", + "@typescript-eslint/types": "4.8.1", + "@typescript-eslint/typescript-estree": "4.8.1", + "debug": "^4.1.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.8.1.tgz", + "integrity": "sha512-r0iUOc41KFFbZdPAdCS4K1mXivnSZqXS5D9oW+iykQsRlTbQRfuFRSW20xKDdYiaCoH+SkSLeIF484g3kWzwOQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.8.1", + "@typescript-eslint/visitor-keys": "4.8.1" + } + }, + "@typescript-eslint/types": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.8.1.tgz", + "integrity": "sha512-ave2a18x2Y25q5K05K/U3JQIe2Av4+TNi/2YuzyaXLAsDx6UZkz1boZ7nR/N6Wwae2PpudTZmHFXqu7faXfHmA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.8.1.tgz", + "integrity": "sha512-bJ6Fn/6tW2g7WIkCWh3QRlaSU7CdUUK52shx36/J7T5oTQzANvi6raoTsbwGM11+7eBbeem8hCCKbyvAc0X3sQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.8.1", + "@typescript-eslint/visitor-keys": "4.8.1", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.8.1.tgz", + "integrity": "sha512-3nrwXFdEYALQh/zW8rFwP4QltqsanCDz4CwWMPiIZmwlk9GlvBeueEIbq05SEq4ganqM0g9nh02xXgv5XI3PeQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.8.1", + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + } + } + }, "@vue/babel-helper-vue-jsx-merge-props": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", @@ -4984,6 +5230,23 @@ } } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + } + } + }, "entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", @@ -5066,22 +5329,24 @@ "dev": true }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.14.0.tgz", + "integrity": "sha512-5YubdnPXrlrYAFCKybPuHIAH++PINe1pmKNc5wQRB9HSbqIK1ywAnntE3Wwua4giKu0bjligf1gLF6qxMGOYRA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.2.1", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.0", + "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", @@ -5090,26 +5355,75 @@ "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", + "levn": "^0.4.1", + "lodash": "^4.17.19", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5120,6 +5434,31 @@ "estraverse": "^4.1.1" } }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", @@ -5129,6 +5468,12 @@ "type-fest": "^0.8.1" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "import-fresh": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", @@ -5139,6 +5484,12 @@ "resolve-from": "^4.0.0" } }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -5146,18 +5497,33 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" } }, "type-fest": { @@ -5165,6 +5531,15 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -5221,9 +5596,9 @@ } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -5644,6 +6019,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", + "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "faye-websocket": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", @@ -7443,13 +7827,13 @@ "dev": true }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "lines-and-columns": { @@ -8161,6 +8545,12 @@ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", "dev": true }, + "normalize-scss": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/normalize-scss/-/normalize-scss-7.0.1.tgz", + "integrity": "sha512-qj16bWnYs+9/ac29IgGjySg4R5qQTp1lXfm7ApFOZNVBYFY8RZ3f8+XQNDDLHeDtI3Ba7Jj4+LuPgz9v/fne2A==", + "dev": true + }, "normalize-url": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", @@ -8400,17 +8790,17 @@ } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "ora": { @@ -9362,9 +9752,9 @@ "dev": true }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prepend-http": { @@ -9667,9 +10057,9 @@ } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, "regexpu-core": { @@ -9890,6 +10280,12 @@ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rgb-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", @@ -9927,6 +10323,12 @@ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true }, + "run-parallel": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", + "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", + "dev": true + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -11321,12 +11723,12 @@ "dev": true }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-fest": { diff --git a/package.json b/package.json index 9f3d515..4edb8e2 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,9 @@ "vue-class-component": "^8.0.0-0" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^2.33.0", - "@typescript-eslint/parser": "^2.33.0", + "@types/leaflet": "^1.5.19", + "@typescript-eslint/eslint-plugin": "^4.1.0", + "@typescript-eslint/parser": "^4.1.0", "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-typescript": "^4.5.9", @@ -23,9 +24,10 @@ "@vue/eslint-config-typescript": "^5.0.2", "axios": "^0.21.0", "babel-eslint": "^10.1.0", - "eslint": "^6.7.2", + "eslint": "^7.5.0", "eslint-plugin-vue": "^7.0.0-0", "leaflet": "^1.7.1", + "normalize-scss": "^7.0.1", "sass": "^1.29.0", "sass-loader": "^10.1.0", "typescript": "~3.9.3", diff --git a/public/index.html b/public/index.html index 9b080c8..0e40cc6 100644 --- a/public/index.html +++ b/public/index.html @@ -13,10 +13,6 @@ - - - - @@ -24,6 +20,7 @@ We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
+ diff --git a/src/App.vue b/src/App.vue index 0120df7..6f4dec4 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,27 +1,76 @@ diff --git a/src/api.ts b/src/api.ts index a552f58..d9fe51f 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,2 +1,129 @@ import axios from 'axios'; +import { + DynmapConfigurationResponse, DynmapMap, DynmapMessageConfig, + DynmapPlayer, + DynmapServerConfig, + DynmapUpdateResponse, + DynmapWorld +} from "@/dynmap"; +export default { + getConfiguration(): Promise { + return axios.get(window.config.url.configuration).then((response): DynmapConfigurationResponse => { + const data = response.data, + config: DynmapServerConfig = { + version: data.dynmapversion || '', + allowChat: data.allowwebchat || false, + chatRequiresLogin: data['webchat-requires-login'] || false, + chatInterval: data['webchat-interval'] || 5, + defaultMap: data.defaultmap || undefined, + defaultWorld: data.defaultworld || undefined, + defaultZoom: data.defaultZoom || 0, + followMap: data.followmap || undefined, + followZoom: data.followzoom || 0, + updateInterval: data.updaterate || 3000, + showLayerControl: data.showlayercontrol || true, + title: data.title || 'Dynmap', + loginEnabled: data['login-enabled'] || false, + loginRequired: data.loginrequired || false, + maxPlayers: data.maxcount || 0, + hash: data.confighash || 0, + }, + messages: DynmapMessageConfig = { + chatNotAllowed: data['msg-chatnotallowed'] || '', + chatRequiresLogin: data['msg-chatrequireslogin'] || '', + chatCooldown: data.spammessage || '', + mapTypes: data['msg-maptypes'] || '', + players: data['msg-players'] || '', + playerJoin: data.joinmessage || '', + playerQuit: data.quitmessage || '', + anonymousJoin: data['msg-hiddennamejoin'] || '', + anonymousQuit: data['msg-hiddennamequit'] || '', + }, + worlds: Array = []; + + (data.worlds || []).forEach((world: any) => { + const maps: Array = []; + + (world.maps || []).forEach((map: any) => { + maps.push({ + world: world.name, + background: map.background || '#000000', + backgroundDay: map.backgroundday || '#000000', + backgroundNight: map.backgroundnight || '#000000', + compassView: map.compassView || 'S', + icon: map.icon || undefined, + imageFormat: map.imageFormat || 'png', + name: map.name || '(Unnamed map)', + nightAndDay: map.nightandday || false, + prefix: map.prefix || '', + protected: map.protected || false, + title: map.title || '', + type: map.type || 'HDMapType', + mapToWorld: map.maptoworld || [0, 0, 0, 0, 0, 0, 0, 0, 0], + worldToMap: map.worldtomap || [0, 0, 0, 0, 0, 0, 0, 0, 0], + nativeZoomLevels: map.mapzoomout || 1, + extraZoomLevels: map.mapzoomin || 0, + }); + }); + + worlds.push({ + seaLevel: world.sealevel || 64, + name: world.name || '(Unnamed world)', + protected: world.protected || false, + title: world.title || '', + height: world.height || 256, + center: { + x: world.center.x || 0, + y: world.center.y || 0, + z: world.center.z || 0 + }, + maps, + }) + }); + + return { + config, + messages, + worlds, + } + }); + }, + + getUpdate(requestId: number, world: string, timestamp: number): Promise { + let url = window.config.url.update; + url = url.replace('{world}', world); + url = url.replace('{timestamp}', timestamp.toString()); + + return axios.get(url).then((response): DynmapUpdateResponse => { + const data = response.data, + players: Array = []; + + (data.players || []).forEach((player: any) => { + players.push({ + account: player.account || "", + health: player.health || 0, + armor: player.armor || 0, + name: player.name || "Steve", + sort: player.sort || 0, + location: { + x: player.x || 0, + y: player.y || 0, + z: player.z || 0, + world: player.world || undefined, + } + }); + }); + + return { + timeOfDay: data.servertime || 0, + thundering: data.isThundering || false, + raining: data.hasStorm || false, + playerCount: data.count || 0, + configHash: data.configHash || 0, + timestamp: data.timestamp || 0, + players, + } + }); + } +} diff --git a/public/css/dynmap_style.css b/src/assets/css/dynmap_style.css similarity index 99% rename from public/css/dynmap_style.css rename to src/assets/css/dynmap_style.css index 3bdc79b..6baf348 100644 --- a/public/css/dynmap_style.css +++ b/src/assets/css/dynmap_style.css @@ -4,6 +4,10 @@ border: 1px solid red; }*/ +html, body { + height: 100%; +} + /******************* * Attribution placement */ @@ -15,6 +19,11 @@ * Page setup */ + +.dynmap { + height: 100%; +} + .dynmap .map .tile img, img { image-rendering: -moz-crisp-edges; image-rendering: pixelated; @@ -206,7 +215,7 @@ margin-right: 0px; } - .dynmap .sidebar < .hitbar:hover { + .dynmap .sidebar > .hitbar:hover { margin-right: 0px; } diff --git a/src/assets/css/images/layers.png b/src/assets/css/images/layers.png new file mode 100644 index 0000000..ef90a08 Binary files /dev/null and b/src/assets/css/images/layers.png differ diff --git a/src/assets/css/images/link.png b/src/assets/css/images/link.png new file mode 100644 index 0000000..c4f00cb Binary files /dev/null and b/src/assets/css/images/link.png differ diff --git a/src/assets/css/images/marker-icon.png b/src/assets/css/images/marker-icon.png new file mode 100644 index 0000000..e2e9f75 Binary files /dev/null and b/src/assets/css/images/marker-icon.png differ diff --git a/src/assets/css/images/marker-icon@2x.png b/src/assets/css/images/marker-icon@2x.png new file mode 100644 index 0000000..0015b64 Binary files /dev/null and b/src/assets/css/images/marker-icon@2x.png differ diff --git a/src/assets/css/images/marker-shadow.png b/src/assets/css/images/marker-shadow.png new file mode 100644 index 0000000..d1e773c Binary files /dev/null and b/src/assets/css/images/marker-shadow.png differ diff --git a/src/assets/css/images/marker.png b/src/assets/css/images/marker.png new file mode 100644 index 0000000..bef032e Binary files /dev/null and b/src/assets/css/images/marker.png differ diff --git a/src/assets/css/images/popup-close.png b/src/assets/css/images/popup-close.png new file mode 100644 index 0000000..c8faec5 Binary files /dev/null and b/src/assets/css/images/popup-close.png differ diff --git a/src/assets/css/images/zoom-in.png b/src/assets/css/images/zoom-in.png new file mode 100644 index 0000000..9f473d6 Binary files /dev/null and b/src/assets/css/images/zoom-in.png differ diff --git a/src/assets/css/images/zoom-out.png b/src/assets/css/images/zoom-out.png new file mode 100644 index 0000000..f0a5b5d Binary files /dev/null and b/src/assets/css/images/zoom-out.png differ diff --git a/public/css/rtgame.css b/src/assets/css/rtgame.css similarity index 100% rename from public/css/rtgame.css rename to src/assets/css/rtgame.css diff --git a/src/assets/images/BiomeKey.png b/src/assets/images/BiomeKey.png new file mode 100644 index 0000000..cb9da47 Binary files /dev/null and b/src/assets/images/BiomeKey.png differ diff --git a/src/assets/images/armor.png b/src/assets/images/armor.png new file mode 100644 index 0000000..0044af1 Binary files /dev/null and b/src/assets/images/armor.png differ diff --git a/src/assets/images/armor_depleted.png b/src/assets/images/armor_depleted.png new file mode 100644 index 0000000..c9bdc24 Binary files /dev/null and b/src/assets/images/armor_depleted.png differ diff --git a/src/assets/images/blank.png b/src/assets/images/blank.png new file mode 100644 index 0000000..e0d1092 Binary files /dev/null and b/src/assets/images/blank.png differ diff --git a/src/assets/images/block_nether_flat.png b/src/assets/images/block_nether_flat.png new file mode 100644 index 0000000..298cdf9 Binary files /dev/null and b/src/assets/images/block_nether_flat.png differ diff --git a/src/assets/images/block_nether_surface.png b/src/assets/images/block_nether_surface.png new file mode 100644 index 0000000..d6d1a51 Binary files /dev/null and b/src/assets/images/block_nether_surface.png differ diff --git a/src/assets/images/block_other.png b/src/assets/images/block_other.png new file mode 100644 index 0000000..6756844 Binary files /dev/null and b/src/assets/images/block_other.png differ diff --git a/src/assets/images/block_skylands.png b/src/assets/images/block_skylands.png new file mode 100644 index 0000000..641155f Binary files /dev/null and b/src/assets/images/block_skylands.png differ diff --git a/src/assets/images/block_the_end_flat.png b/src/assets/images/block_the_end_flat.png new file mode 100644 index 0000000..574d213 Binary files /dev/null and b/src/assets/images/block_the_end_flat.png differ diff --git a/src/assets/images/block_the_end_surface.png b/src/assets/images/block_the_end_surface.png new file mode 100644 index 0000000..69bcc32 Binary files /dev/null and b/src/assets/images/block_the_end_surface.png differ diff --git a/src/assets/images/block_world_biome.png b/src/assets/images/block_world_biome.png new file mode 100644 index 0000000..a72932a Binary files /dev/null and b/src/assets/images/block_world_biome.png differ diff --git a/src/assets/images/block_world_cave.png b/src/assets/images/block_world_cave.png new file mode 100644 index 0000000..b6a547b Binary files /dev/null and b/src/assets/images/block_world_cave.png differ diff --git a/src/assets/images/block_world_flat.png b/src/assets/images/block_world_flat.png new file mode 100644 index 0000000..1a511bd Binary files /dev/null and b/src/assets/images/block_world_flat.png differ diff --git a/src/assets/images/block_world_surface.png b/src/assets/images/block_world_surface.png new file mode 100644 index 0000000..603c6d5 Binary files /dev/null and b/src/assets/images/block_world_surface.png differ diff --git a/src/assets/images/book.png b/src/assets/images/book.png new file mode 100644 index 0000000..727dcda Binary files /dev/null and b/src/assets/images/book.png differ diff --git a/src/assets/images/cave_off.png b/src/assets/images/cave_off.png new file mode 100644 index 0000000..500d987 Binary files /dev/null and b/src/assets/images/cave_off.png differ diff --git a/src/assets/images/cave_on.png b/src/assets/images/cave_on.png new file mode 100644 index 0000000..0639576 Binary files /dev/null and b/src/assets/images/cave_on.png differ diff --git a/src/assets/images/chat_bubble.png b/src/assets/images/chat_bubble.png new file mode 100644 index 0000000..51e11a4 Binary files /dev/null and b/src/assets/images/chat_bubble.png differ diff --git a/src/assets/images/chat_cursor.png b/src/assets/images/chat_cursor.png new file mode 100644 index 0000000..e3d38ab Binary files /dev/null and b/src/assets/images/chat_cursor.png differ diff --git a/src/assets/images/clock_day.png b/src/assets/images/clock_day.png new file mode 100644 index 0000000..6ed0dae Binary files /dev/null and b/src/assets/images/clock_day.png differ diff --git a/src/assets/images/clock_night.png b/src/assets/images/clock_night.png new file mode 100644 index 0000000..0832f0c Binary files /dev/null and b/src/assets/images/clock_night.png differ diff --git a/src/assets/images/compass.png b/src/assets/images/compass.png new file mode 100644 index 0000000..2614dd3 Binary files /dev/null and b/src/assets/images/compass.png differ diff --git a/src/assets/images/compass_E.png b/src/assets/images/compass_E.png new file mode 100644 index 0000000..a12f987 Binary files /dev/null and b/src/assets/images/compass_E.png differ diff --git a/src/assets/images/compass_N.png b/src/assets/images/compass_N.png new file mode 100644 index 0000000..4794e36 Binary files /dev/null and b/src/assets/images/compass_N.png differ diff --git a/src/assets/images/compass_NE.png b/src/assets/images/compass_NE.png new file mode 100644 index 0000000..e4c6574 Binary files /dev/null and b/src/assets/images/compass_NE.png differ diff --git a/src/assets/images/compass_NW.png b/src/assets/images/compass_NW.png new file mode 100644 index 0000000..b657abf Binary files /dev/null and b/src/assets/images/compass_NW.png differ diff --git a/src/assets/images/compass_SW.png b/src/assets/images/compass_SW.png new file mode 100644 index 0000000..f85c0d3 Binary files /dev/null and b/src/assets/images/compass_SW.png differ diff --git a/src/assets/images/compass_W.png b/src/assets/images/compass_W.png new file mode 100644 index 0000000..a90055f Binary files /dev/null and b/src/assets/images/compass_W.png differ diff --git a/src/assets/images/compass_alt.png b/src/assets/images/compass_alt.png new file mode 100644 index 0000000..0e7cc4b Binary files /dev/null and b/src/assets/images/compass_alt.png differ diff --git a/src/assets/images/compass_flat.png b/src/assets/images/compass_flat.png new file mode 100644 index 0000000..3a81604 Binary files /dev/null and b/src/assets/images/compass_flat.png differ diff --git a/src/assets/images/dynmap.ico b/src/assets/images/dynmap.ico new file mode 100644 index 0000000..035da52 Binary files /dev/null and b/src/assets/images/dynmap.ico differ diff --git a/src/assets/images/follow_off.png b/src/assets/images/follow_off.png new file mode 100644 index 0000000..ba506d0 Binary files /dev/null and b/src/assets/images/follow_off.png differ diff --git a/src/assets/images/follow_on.png b/src/assets/images/follow_on.png new file mode 100644 index 0000000..2fb7be7 Binary files /dev/null and b/src/assets/images/follow_on.png differ diff --git a/src/assets/images/heart.png b/src/assets/images/heart.png new file mode 100644 index 0000000..fba8477 Binary files /dev/null and b/src/assets/images/heart.png differ diff --git a/src/assets/images/heart_depleted.png b/src/assets/images/heart_depleted.png new file mode 100644 index 0000000..c8aef57 Binary files /dev/null and b/src/assets/images/heart_depleted.png differ diff --git a/src/assets/images/home.png b/src/assets/images/home.png new file mode 100644 index 0000000..5b15f03 Binary files /dev/null and b/src/assets/images/home.png differ diff --git a/src/assets/images/list_off.png b/src/assets/images/list_off.png new file mode 100644 index 0000000..b7be11b Binary files /dev/null and b/src/assets/images/list_off.png differ diff --git a/src/assets/images/list_on.png b/src/assets/images/list_on.png new file mode 100644 index 0000000..285f76e Binary files /dev/null and b/src/assets/images/list_on.png differ diff --git a/src/assets/images/moon.png b/src/assets/images/moon.png new file mode 100644 index 0000000..0283a87 Binary files /dev/null and b/src/assets/images/moon.png differ diff --git a/src/assets/images/player.png b/src/assets/images/player.png new file mode 100644 index 0000000..212039f Binary files /dev/null and b/src/assets/images/player.png differ diff --git a/src/assets/images/player_death.png b/src/assets/images/player_death.png new file mode 100644 index 0000000..9abd211 Binary files /dev/null and b/src/assets/images/player_death.png differ diff --git a/src/assets/images/player_face.png b/src/assets/images/player_face.png new file mode 100644 index 0000000..206c6f3 Binary files /dev/null and b/src/assets/images/player_face.png differ diff --git a/src/assets/images/player_follow_off.png b/src/assets/images/player_follow_off.png new file mode 100644 index 0000000..935e7c6 Binary files /dev/null and b/src/assets/images/player_follow_off.png differ diff --git a/src/assets/images/player_follow_on.gif b/src/assets/images/player_follow_on.gif new file mode 100644 index 0000000..6937e81 Binary files /dev/null and b/src/assets/images/player_follow_on.gif differ diff --git a/src/assets/images/player_follow_on.png b/src/assets/images/player_follow_on.png new file mode 100644 index 0000000..fa790c5 Binary files /dev/null and b/src/assets/images/player_follow_on.png differ diff --git a/src/assets/images/player_travel.png b/src/assets/images/player_travel.png new file mode 100644 index 0000000..03ea756 Binary files /dev/null and b/src/assets/images/player_travel.png differ diff --git a/src/assets/images/scrolldown.png b/src/assets/images/scrolldown.png new file mode 100644 index 0000000..9d07aa6 Binary files /dev/null and b/src/assets/images/scrolldown.png differ diff --git a/src/assets/images/scrollup.png b/src/assets/images/scrollup.png new file mode 100644 index 0000000..b6b6c0c Binary files /dev/null and b/src/assets/images/scrollup.png differ diff --git a/src/assets/images/server.png b/src/assets/images/server.png new file mode 100644 index 0000000..e28417c Binary files /dev/null and b/src/assets/images/server.png differ diff --git a/src/assets/images/sidebar_hint.png b/src/assets/images/sidebar_hint.png new file mode 100644 index 0000000..15e2b7d Binary files /dev/null and b/src/assets/images/sidebar_hint.png differ diff --git a/src/assets/images/sign.png b/src/assets/images/sign.png new file mode 100644 index 0000000..8d8573c Binary files /dev/null and b/src/assets/images/sign.png differ diff --git a/src/assets/images/sign_home.png b/src/assets/images/sign_home.png new file mode 100644 index 0000000..5ecfcec Binary files /dev/null and b/src/assets/images/sign_home.png differ diff --git a/src/assets/images/sign_sign.png b/src/assets/images/sign_sign.png new file mode 100644 index 0000000..5eae09b Binary files /dev/null and b/src/assets/images/sign_sign.png differ diff --git a/src/assets/images/sign_sign_alt.png b/src/assets/images/sign_sign_alt.png new file mode 100644 index 0000000..9834150 Binary files /dev/null and b/src/assets/images/sign_sign_alt.png differ diff --git a/src/assets/images/sign_warp.png b/src/assets/images/sign_warp.png new file mode 100644 index 0000000..9f05e51 Binary files /dev/null and b/src/assets/images/sign_warp.png differ diff --git a/src/assets/images/spawn.png b/src/assets/images/spawn.png new file mode 100644 index 0000000..177650b Binary files /dev/null and b/src/assets/images/spawn.png differ diff --git a/src/assets/images/sun.png b/src/assets/images/sun.png new file mode 100644 index 0000000..40e3962 Binary files /dev/null and b/src/assets/images/sun.png differ diff --git a/src/assets/images/warp.png b/src/assets/images/warp.png new file mode 100644 index 0000000..8ed89e7 Binary files /dev/null and b/src/assets/images/warp.png differ diff --git a/src/assets/images/weather_stormy.png b/src/assets/images/weather_stormy.png new file mode 100644 index 0000000..45808fb Binary files /dev/null and b/src/assets/images/weather_stormy.png differ diff --git a/src/assets/images/weather_stormy_day.png b/src/assets/images/weather_stormy_day.png new file mode 100644 index 0000000..dea2320 Binary files /dev/null and b/src/assets/images/weather_stormy_day.png differ diff --git a/src/assets/images/weather_stormy_night.png b/src/assets/images/weather_stormy_night.png new file mode 100644 index 0000000..fe08ba8 Binary files /dev/null and b/src/assets/images/weather_stormy_night.png differ diff --git a/src/assets/images/weather_sunny.png b/src/assets/images/weather_sunny.png new file mode 100644 index 0000000..8ef8cbd Binary files /dev/null and b/src/assets/images/weather_sunny.png differ diff --git a/src/assets/images/weather_sunny_day.png b/src/assets/images/weather_sunny_day.png new file mode 100644 index 0000000..94ce5b0 Binary files /dev/null and b/src/assets/images/weather_sunny_day.png differ diff --git a/src/assets/images/weather_sunny_night.png b/src/assets/images/weather_sunny_night.png new file mode 100644 index 0000000..fe4fd8b Binary files /dev/null and b/src/assets/images/weather_sunny_night.png differ diff --git a/src/assets/images/weather_thunder.png b/src/assets/images/weather_thunder.png new file mode 100644 index 0000000..07bbfc0 Binary files /dev/null and b/src/assets/images/weather_thunder.png differ diff --git a/src/assets/images/weather_thunder_day.png b/src/assets/images/weather_thunder_day.png new file mode 100644 index 0000000..8900521 Binary files /dev/null and b/src/assets/images/weather_thunder_day.png differ diff --git a/src/assets/images/weather_thunder_night.png b/src/assets/images/weather_thunder_night.png new file mode 100644 index 0000000..63b359e Binary files /dev/null and b/src/assets/images/weather_thunder_night.png differ diff --git a/src/assets/images/window_close.png b/src/assets/images/window_close.png new file mode 100644 index 0000000..586de30 Binary files /dev/null and b/src/assets/images/window_close.png differ diff --git a/src/assets/images/window_close_hover.png b/src/assets/images/window_close_hover.png new file mode 100644 index 0000000..08656f6 Binary files /dev/null and b/src/assets/images/window_close_hover.png differ diff --git a/src/assets/images/window_open.png b/src/assets/images/window_open.png new file mode 100644 index 0000000..f84684c Binary files /dev/null and b/src/assets/images/window_open.png differ diff --git a/src/assets/images/window_pinned.png b/src/assets/images/window_pinned.png new file mode 100644 index 0000000..9051e4f Binary files /dev/null and b/src/assets/images/window_pinned.png differ diff --git a/src/assets/images/window_pinned_hover.png b/src/assets/images/window_pinned_hover.png new file mode 100644 index 0000000..e1f963d Binary files /dev/null and b/src/assets/images/window_pinned_hover.png differ diff --git a/src/assets/images/window_unpinned.png b/src/assets/images/window_unpinned.png new file mode 100644 index 0000000..f84684c Binary files /dev/null and b/src/assets/images/window_unpinned.png differ diff --git a/src/assets/images/zoom_in.png b/src/assets/images/zoom_in.png new file mode 100644 index 0000000..8b91d8d Binary files /dev/null and b/src/assets/images/zoom_in.png differ diff --git a/src/assets/images/zoom_out.png b/src/assets/images/zoom_out.png new file mode 100644 index 0000000..9af74b2 Binary files /dev/null and b/src/assets/images/zoom_out.png differ diff --git a/src/components/Leaflet.vue b/src/components/Leaflet.vue new file mode 100644 index 0000000..d386423 --- /dev/null +++ b/src/components/Leaflet.vue @@ -0,0 +1,50 @@ + + + + + \ No newline at end of file diff --git a/src/components/Map.vue b/src/components/Map.vue deleted file mode 100644 index a6608d2..0000000 --- a/src/components/Map.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/components/PlayerList.vue b/src/components/PlayerList.vue index 39fe14a..e9fb0e5 100644 --- a/src/components/PlayerList.vue +++ b/src/components/PlayerList.vue @@ -1,27 +1,34 @@ - \ No newline at end of file diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index 78bc349..3f72479 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -2,154 +2,26 @@ - diff --git a/src/components/WorldList.vue b/src/components/WorldList.vue new file mode 100644 index 0000000..7c1328b --- /dev/null +++ b/src/components/WorldList.vue @@ -0,0 +1,34 @@ + + + + + \ No newline at end of file diff --git a/src/components/WorldListItem.vue b/src/components/WorldListItem.vue new file mode 100644 index 0000000..af34bdb --- /dev/null +++ b/src/components/WorldListItem.vue @@ -0,0 +1,62 @@ + + + + + \ No newline at end of file diff --git a/src/components/map/layer/MapLayer.vue b/src/components/map/layer/MapLayer.vue new file mode 100644 index 0000000..ef11b66 --- /dev/null +++ b/src/components/map/layer/MapLayer.vue @@ -0,0 +1,85 @@ + + + \ No newline at end of file diff --git a/src/components/map/layer/PlayersLayer.vue b/src/components/map/layer/PlayersLayer.vue new file mode 100644 index 0000000..9beab9e --- /dev/null +++ b/src/components/map/layer/PlayersLayer.vue @@ -0,0 +1,41 @@ + + + + + \ No newline at end of file diff --git a/src/components/map/marker/PlayerMarker.vue b/src/components/map/marker/PlayerMarker.vue new file mode 100644 index 0000000..0db7c1c --- /dev/null +++ b/src/components/map/marker/PlayerMarker.vue @@ -0,0 +1,33 @@ + + + \ No newline at end of file diff --git a/src/dynmap.d.ts b/src/dynmap.d.ts new file mode 100644 index 0000000..0047356 --- /dev/null +++ b/src/dynmap.d.ts @@ -0,0 +1,154 @@ +import {ControlPosition, LeafletMouseEvent} from "leaflet"; + +declare global { + interface Window { + config: DynmapConfig + } +} + +type DynmapConfig = { + url: DynmapUrlConfig; +}; + +type DynmapUrlConfig = { + configuration: string; + update: string; + sendmessage: string; + login: string; + register: string; + tiles: string; + markers: string; +} + +interface DynmapServerConfig { + version: string; + allowChat: boolean; + chatRequiresLogin: boolean; + chatInterval: number; + defaultMap?: string; + defaultWorld?: string; + defaultZoom?: number; + followMap?: string; + followZoom?: number; + updateInterval: number; + showLayerControl: boolean; + title: string; + loginEnabled: boolean; + loginRequired: boolean; + maxPlayers: number; + hash: number; +} + +interface DynmapMessageConfig { + chatNotAllowed: string; + chatRequiresLogin: string; + chatCooldown: string; + mapTypes: string; + players: string; + playerJoin: string; + playerQuit: string; + anonymousJoin: string; + anonymousQuit: string; +} + +interface DynmapWorld { + seaLevel: number; + name: string; + protected: boolean; + title: string; + height: number; + center: Coordinate; + maps: Array; +} + +interface DynmapMap { + world: string; + background: string; + backgroundDay: string; + backgroundNight: string; + compassView: string; + icon: string; + imageFormat: string; + name: string; + nightAndDay: boolean; + prefix: string; + protected: boolean; + title: string; + type: string; + mapToWorld: [number, number, number, number, number, number, number, number, number]; + worldToMap: [number, number, number, number, number, number, number, number, number]; + nativeZoomLevels: number; + extraZoomLevels: number; +} + +interface Coordinate { + x: number; + y: number; + z: number; +} + +interface DynmapLocation { + x: number; + y: number; + z: number; + world?: string; +} + +interface DynmapConfigurationResponse { + config: DynmapServerConfig, + messages: DynmapMessageConfig, + worlds: Array, +} + +interface DynmapUpdateResponse { + configHash: number; + playerCount: number; + raining: boolean; + thundering: boolean; + timeOfDay: number; + players: Array; + timestamp: number; + //TODO: Tiles etc +} + +interface DynmapPlayer { + account: string + armor: number + health: number + name: string + sort: number + location: DynmapLocation; +} + +declare module 'leaflet' { + namespace Control { + function extend(props: T): { new(...args: any[]): T } & typeof Control; + + class CoordinatesControl extends Control { + constructor(options: CoordinatesControlOptions); + + options: CoordinatesControlOptions + _coordsContainer?: HTMLElement + _regionContainer?: HTMLElement + _chunkContainer?: HTMLElement + _map?: L.Map + + _onMouseMove(event: LeafletMouseEvent): void + + _onMouseOut(event: LeafletMouseEvent): void + + _update(): void + + } + + interface CoordinatesControlOptions { + showY: boolean + showRegion: boolean + showChunk: boolean + label: string + position: ControlPosition + } + + function coordinatesControl(options: CoordinatesControlOptions): CoordinatesControl; + } +} diff --git a/src/leaflet/control/CoordinatesControl.js b/src/leaflet/control/CoordinatesControl.js new file mode 100644 index 0000000..e3bdc98 --- /dev/null +++ b/src/leaflet/control/CoordinatesControl.js @@ -0,0 +1,108 @@ +import L from 'leaflet'; + +L.Control.CoordinatesControl = L.Control.extend({ + options: { + showY: true, + showRegion: false, + showChunk: false, + label: 'x,y,z: ', + position: 'topleft', + }, + + _coordsContainer: undefined, + _regionContainer: undefined, + _chunkContainer: undefined, + + constructor(options) { + L.Util.setOptions(this, options); + }, + + onAdd(map) { + var container = L.DomUtil.create('div', 'coord-control'); + + if (!this.options.showY) { + container.classList.add('coord-control-noy'); + } + + this._coordsContainer = L.DomUtil.create('span', 'coord-control-value'); + this._coordsContainer.innerText = this.options.showY ? '---,---,---' : '---,---'; + this._coordsContainer.dataset.label = this.options.label; + container.insertAdjacentElement('beforeend', this._coordsContainer); + + if (this.options.showRegion) { + this._regionContainer = L.DomUtil.create('span', 'coord-control-value'); + this._regionContainer.innerText = '--------'; + container.insertAdjacentElement('beforeend', this._regionContainer); + } + + if (this.options.showChunk) { + this._chunkContainer = L.DomUtil.create('span', 'coord-control-value'); + this._chunkContainer.innerText = '---,---'; + this._chunkContainer.dataset.label = 'Chunk: '; + container.insertAdjacentElement('beforeend', this._chunkContainer); + } + + map.on('mousemove', this._onMouseMove, this); + map.on('mouseout', this._onMouseOut, this); + + this._update(); + return container; + }, + + remove() { + if (!this._map) { + return this; + } + + this._map.on('mousemove', this._onMouseMove, this); + this._map.on('mouseout', this._onMouseOut, this); + L.Control.prototype.remove.call(this); + + return this; + }, + + _onMouseMove(event) { + if (!this._map) { + return; + } + + var loc = dynmap.getProjection().fromLatLngToLocation(event.latlng, dynmap.world.sealevel + 1); + + if (this.options.showY) { + this._coordsContainer.innerText = Math.round(loc.x) + ',' + loc.y + ',' + Math.round(loc.z); + } else { + this._coordsContainer.innerText = Math.round(loc.x) + ',' + Math.round(loc.z); + } + + if (this.options.showRegion) { + this._regionContainer.innerText = 'r.' + Math.floor(loc.x / 512) + '.' + Math.floor(loc.z / 512) + '.mca'; + } + + if (this.options.showChunk) { + this._chunkContainer.innerText = 'Chunk: ' + Math.floor(loc.x / 16) + ',' + Math.floor(loc.z / 16); + } + }, + + _onMouseOut() { + if (!this._map) { + return; + } + + if (this.options.showY) { + this._coordsContainer.innerText = '---,---'; + } else { + this._coordsContainer.innerText = '---,---,---'; + } + + if (this.options.showRegion) { + this._regionContainer.innerText = '--------'; + } + + if (this.options.showChunk) { + this._chunkContainer.innerText = '---,---'; + } + }, + + _update() { + } +}); diff --git a/src/leaflet/control/LinkControl.js b/src/leaflet/control/LinkControl.js new file mode 100644 index 0000000..c1335fe --- /dev/null +++ b/src/leaflet/control/LinkControl.js @@ -0,0 +1,51 @@ +import L from 'leaflet'; + +const LinkControl = L.Control.extend({ + options: {position: 'bottomleft'}, + + onAdd: function (map) { + this._map = map; + this._container = L.DomUtil.create('div', 'dynmap-link'); + + this._linkButton = this._createButton( + 'Link', 'dynmap-link-button', this._follow, this); + + this._container.appendChild(this._linkButton); + return this._container; + }, + + getContainer: function () { + return this._container; + }, + + getPosition: function () { + return this.options.position; + }, + + _createButton: function (title, className, fn, context) { + var link = document.createElement('a'); + link.href = '#'; + link.title = title; + link.className = className; + link.onmouseover = function () { + link.href = dynmap.getLink(); + }; + + L.DomEvent.disableClickPropagation(link); + L.DomEvent.addListener(link, 'click', L.DomEvent.preventDefault); + L.DomEvent.addListener(link, 'click', fn, context); + + return link; + }, + + _follow: function () { + // var url = dynmap.getLink(); + // window.location = url; + } +}); + +// var link = new dynmapLink(); +// dynmap.map.addControl(link); +// } + +export default LinkControl; \ No newline at end of file diff --git a/src/leaflet/control/LogoControl.js b/src/leaflet/control/LogoControl.js new file mode 100644 index 0000000..a3787a0 --- /dev/null +++ b/src/leaflet/control/LogoControl.js @@ -0,0 +1,50 @@ +import L from 'leaflet'; + +const LogoControl = L.Control.extend({ + onAdd: function (map) { + this._container = L.DomUtil.create('div', 'leaflet-control-attribution'); + this._map = map; + this._update(); + return this._container; + }, + + getPosition: function () { + if (configuration.position == 'top-left') + return 'topleft'; + else if (configuration.position == 'top-right') + return 'topright'; + else if (configuration.position == 'bottom-left') + return 'bottomleft'; + else + return 'bottomright'; + }, + + getContainer: function () { + return this._container; + }, + + _update: function () { + if (!this._map) return; + var c = this._container; + if (configuration.linkurl) { + c = $('').attr('href', configuration.linkurl).appendTo(c)[0]; + } + if (configuration.logourl) { + $(c).append($('').attr('src', configuration.logourl).attr('alt', configuration.text).appendTo(c)[0]); + } else { + $(c).text(configuration.text); + } + } +}); +// +// dynmap.map.options.attributionControl = false; +// if (dynmap.map.attributionControl) { +// dynmap.map.removeControl(dynmap.map.attributionControl); +// dynmap.map.attributionControl = null; +// } +// var l = new Logo(); +// dynmap.map.addControl(l); +// } +// ; + +export default LogoControl; \ No newline at end of file diff --git a/src/leaflet/mapType/HDMapType.js b/src/leaflet/mapType/HDMapType.js new file mode 100644 index 0000000..71057ae --- /dev/null +++ b/src/leaflet/mapType/HDMapType.js @@ -0,0 +1,47 @@ +import DynmapTileLayer from "@/leaflet/tileLayer/DynmapTileLayer"; +import HDProjection from "@/leaflet/projection/HDProjection"; +import L from 'leaflet'; + +const HDMapType = DynmapTileLayer.extend({ + projection: undefined, + options: { + maxZoom: 1, + maxNativeZoom: 1, + worldName: '', + prefix: '', + errorTileUrl: 'images/blank.png', + }, + initialize(options) { + DynmapTileLayer.prototype.initialize.call(this, options); + options.zoomReverse = true; + options.tileSize = 128; + options.minZoom = 0; + L.Util.setOptions(this, options); + this.projection = new HDProjection(Object.assign(options, {map: this})); + }, + + getTileName: function(coords) { + let info = this.getTileInfo(coords); + // Y is inverted for HD-map. + info.y = -info.y; + info.scaledy = info.y >> 5; + return `${info.prefix}${info.nightday}/${info.scaledx}_${info.scaledy}/${info.zoom}${info.x}_${info.y}.${info.fmt}`; + }, + zoomprefix: function(amount) { + // amount == 0 -> '' + // amount == 1 -> 'z_' + // amount == 2 -> 'zz_' + return 'zzzzzzzzzzzzzzzzzzzzzz'.substr(0, amount) + (amount === 0 ? '' : '_'); + } +}); + +// maptypes.HDMapType = function(options) { return new HDMapType(options); }; + +const hdMapType = (options) => { + return new HDMapType(options); +} + +export { + HDMapType, + hdMapType +}; \ No newline at end of file diff --git a/src/leaflet/marker/PlayerMarker.js b/src/leaflet/marker/PlayerMarker.js new file mode 100644 index 0000000..dc3cd28 --- /dev/null +++ b/src/leaflet/marker/PlayerMarker.js @@ -0,0 +1,156 @@ +import L from 'leaflet'; + +const PlayerMarker = L.Marker.extend({ + options: { + smallFace: true, + showSkinFace: false, + showBody: false, + showHealth: false, + }, + + initialize: function (player, options) { + this._player = player; + options.draggable = false; + options.icon = new PlayerIcon(player, { + smallFace: options.smallFace, + showSkinFace: options.showSkinFace, + showBody: options.showBody, + showHealth: options.showHealth, + }); + + L.Util.setOptions(this, options); + //this._latlng = toLatLng(latlng); //TODO + }, +}); + +var PlayerIcon = L.DivIcon.extend({ + _player: null, + _container: null, + _playerImage: null, + _playerName: null, + + _playerHealth: null, + _playerHealthBg: null, + _playerHealthBar: null, + _playerArmourBg: null, + _playerArmourBar: null, + + options: { + smallFace: true, + showSkinFace: false, + showBody: false, + showHealth: false, + }, + + initialize: function (player, options) { + this._player = player; + L.Util.setOptions(this, options); + }, + + createIcon: function (oldIcon) { + if (oldIcon) { + L.DomUtil.remove(oldIcon); + } + + var player = this._player; + + this._container = document.createElement('div'); + + // var markerPosition = dynmap.getProjection().fromLocationToLatLng(player.location); + // player.marker.setLatLng(markerPosition); + + this._container.classList.add('Marker', 'playerMarker', 'leaflet-marker-icon'); + + this._playerImage = document.createElement('img'); + this._playerImage.classList.add(this.options.smallFace ? 'playerIconSm' : 'playerIcon'); + this._playerImage.src = 'images/player.png'; + + this._playerName = document.createElement('span'); + this._playerName.classList.add(this.options.smallFace ? 'playerNameSm' : 'playerName'); + this._playerName.innerText = player.name; + + this._container.insertAdjacentElement('beforeend', this._playerImage); + this._container.insertAdjacentElement('beforeend', this._playerName); + + if (this.options.showSkinFace) { + var that = this; + + if (this.options.smallFace) { + getMinecraftHead(player.account, 16, function (head) { + that._playerImage.src = head.src; + }); + } else if (this.options.showBody) { + getMinecraftHead(player.account, 'body', function (head) { + that._playerImage.src = head.src; + }); + } else { + getMinecraftHead(player.account, 32, function (head) { + that._playerImage.src = head.src; + }); + } + } + + if (this.options.showHealth) { + this._playerHealth = document.createElement('div'); + + this._playerHealth.classList.add(this.options.smallFace ? 'healthContainerSm' : 'healthContainer'); + this._container.insertAdjacentElement('beforeend', this._playerHealth) + + this._playerHealthBar = document.createElement('div'); + this._playerHealthBar.classList.add('playerHealth'); + + this._playerArmourBar = document.createElement('div'); + this._playerArmourBar.classList.add('playerHealth'); + + this._playerHealthBg = document.createElement('div'); + this._playerArmourBg = document.createElement('div'); + + this._playerHealthBg.classList.add('playerHealthBackground'); + this._playerArmourBar.classList.add('playerArmorBackground'); + + this._playerHealthBg.insertAdjacentElement('beforeend', this._playerHealthBar); + this._playerArmourBg.insertAdjacentElement('beforeend', this._playerArmourBar); + + this._playerHealth.insertAdjacentElement('beforeend', this._playerHealthBg); + this._playerHealth.insertAdjacentElement('beforeend', this._playerArmourBg); + + this._playerHealth.hidden = true; + } else { + this._playerName.classList.add('playerNameNoHealth'); + } + + return this._container; + + // var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'), + // options = this.options; + // + // if (options.html instanceof Element) { + // empty(div); + // div.appendChild(options.html); + // } else { + // div.innerHTML = options.html !== false ? options.html : ''; + // } + // + // if (options.bgPos) { + // var bgPos = toPoint(options.bgPos); + // div.style.backgroundPosition = (-bgPos.x) + 'px ' + (-bgPos.y) + 'px'; + // } + // this._setIconStyles(div, 'icon'); + // + // return div; + }, + + update() { + this._playerName.innerText = this.player.name; + + if (this.options.player.health !== undefined && this.options.player.armor !== undefined) { + this.options.player.healthContainer.hidden = false; + this._this.options.playerHealthBar.style.width = Math.ceil(this.options.player.health * 2.5) + 'px'; + this._this.options.playerArmourBar.style.width = Math.ceil(this.options.player.armor * 2.5) + 'px'; + } else { + this.options.player.healthContainer.hidden = true; + } + } +}); + +export default PlayerMarker; \ No newline at end of file diff --git a/src/leaflet/projection/DynmapProjection.js b/src/leaflet/projection/DynmapProjection.js new file mode 100644 index 0000000..d637a38 --- /dev/null +++ b/src/leaflet/projection/DynmapProjection.js @@ -0,0 +1,15 @@ +import L from 'leaflet'; + +const DynmapProjection = L.Class.extend({ + initialize: function (options) { + L.Util.setOptions(this, options); + }, + fromLocationToLatLng: function () { + throw "fromLocationToLatLng not implemented"; + }, + fromLatLngToLocation: function () { + return null; + } +}); + +export default DynmapProjection; \ No newline at end of file diff --git a/src/leaflet/projection/HDProjection.js b/src/leaflet/projection/HDProjection.js new file mode 100644 index 0000000..c3bf9cc --- /dev/null +++ b/src/leaflet/projection/HDProjection.js @@ -0,0 +1,25 @@ +import DynmapProjection from "@/leaflet/projection/DynmapProjection"; +import L from 'leaflet'; + +const HDProjection = DynmapProjection.extend({ + fromLocationToLatLng: function (location) { + var wtp = this.options.worldtomap; + var lat = wtp[3] * location.x + wtp[4] * location.y + wtp[5] * location.z; + var lng = wtp[0] * location.x + wtp[1] * location.y + wtp[2] * location.z; + + return new L.LatLng( + -((128 - lat) / (1 << this.options.mapzoomout)), + lng / (1 << this.options.mapzoomout), + true); + }, + fromLatLngToLocation: function (latlon, y) { + var ptw = this.options.maptoworld; + var lat = latlon.lng * (1 << this.options.mapzoomout); + var lon = 128 + latlon.lat * (1 << this.options.mapzoomout); + var x = ptw[0] * lat + ptw[1] * lon + ptw[2] * y; + var z = ptw[6] * lat + ptw[7] * lon + ptw[8] * y; + return {x: x, y: y, z: z}; + } +}); + +export default HDProjection; diff --git a/src/leaflet/tileLayer/DynmapTileLayer.js b/src/leaflet/tileLayer/DynmapTileLayer.js new file mode 100644 index 0000000..0987c68 --- /dev/null +++ b/src/leaflet/tileLayer/DynmapTileLayer.js @@ -0,0 +1,128 @@ +import L from 'leaflet'; + +const DynmapTileLayer = L.TileLayer.extend({ + options: { + worldName: '', + prefix: '', + }, + + _cachedTileUrls: null, + _namedTiles: null, + + initialize(options) { + L.TileLayer.prototype.initialize.call(this, options); + this._cachedTileUrls = {}; + this._namedTiles = {}; + L.Util.setOptions(this, options); + }, + + getProjection: function () { + return this.projection; + }, + + getTileName: function() { + throw "getTileName not implemented"; + }, + + getTileUrl: function (coords) { + var tileName = this.getTileName(coords, coords.z), + url = this._cachedTileUrls[tileName]; + + if (!url) { + let path = escape(`${this.options.worldName}/${tileName}`); + url = `${window.config.url.tiles}${path}`; + this._cachedTileUrls[tileName] = url; + } + + return url; + }, + + updateNamedTile: function (name) { + var tile = this._namedTiles[name]; + delete this._cachedTileUrls[name]; + + if (tile) { + tile.src = this._cachedTileUrls[name] = this.options.dynmap.getTileUrl(name); + } + }, + + createTile(coords, done) { + var tile = L.TileLayer.prototype.createTile.call(this, coords, done), + name = this.getTileName(coords); + + tile.tileName = name; + + // console.log("Adding " + tile.tileName); + this._namedTiles[name] = tile; + + return tile; + }, + + // stops loading all tiles in the background layer + _abortLoading: function () { + var i, tile; + for (i in this._tiles) { + if (!Object.prototype.hasOwnProperty.call(this._tiles, i)) { + continue; + } + + tile = this._tiles[i] + + if (tile.coords.z !== this._tileZoom) { + if (!tile.complete && tile.el && tile.el.tileName) { + // console.log("Aborting " + tile.el.tileName); + delete this._namedTiles[tile.el.tileName]; + } + } + } + + L.TileLayer.prototype._abortLoading.call(this); + }, + + _removeTile: function (key) { + var tile = this._tiles[key]; + + if (!tile) { + return; + } + + var tileName = tile.el.tileName; + + if (tileName) { + // console.log("Removing " + tileName); + delete this._namedTiles[tileName]; + delete this._cachedTileUrls[tileName]; + } + + L.TileLayer.prototype._removeTile.call(this, key); + }, + + // Some helper functions. + zoomprefix: function (amount) { + return 'zzzzzzzzzzzzzzzzzzzzzz'.substr(0, amount); + }, + + getTileInfo: function (coords) { + // zoom: max zoomed in = this.options.maxZoom, max zoomed out = 0 + // izoom: max zoomed in = 0, max zoomed out = this.options.maxZoom + // zoomoutlevel: izoom < mapzoomin -> 0, else -> izoom - mapzoomin (which ranges from 0 till mapzoomout) + var izoom = this._getZoomForUrl(); + var zoomoutlevel = Math.max(0, izoom - (this.options.maxZoom - this.options.maxNativeZoom)); + var scale = 1 << zoomoutlevel; + var x = scale * coords.x; + var y = scale * coords.y; + return { + prefix: this.options.prefix, + nightday: (this.options.nightandday && this.options.dynmap.serverday) ? '_day' : '', + scaledx: x >> 5, + scaledy: y >> 5, + zoom: this.zoomprefix(zoomoutlevel), + zoomprefix: (zoomoutlevel == 0) ? "" : (this.zoomprefix(zoomoutlevel) + "_"), + x: x, + y: y, + fmt: this.options['image-format'] || 'png' + }; + } +}); + +export default DynmapTileLayer; \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index b66c527..cd4f023 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,13 @@ import { createApp } from 'vue' import App from './App.vue' -import store from "@/store"; +import {store} from "@/store"; -const app = createApp(App); -app.use(store).mount('#mcmap'); \ No newline at end of file +import 'leaflet/dist/leaflet.css'; +import 'normalize-scss/sass/normalize/_import-now.scss'; +import './assets/css/dynmap_style.css'; +import './assets/css/rtgame.css'; + +const app = createApp(App).use(store); + +app.config.performance = true; +app.mount('#mcmap'); \ No newline at end of file diff --git a/src/store.ts b/src/store.ts deleted file mode 100644 index b45dc8e..0000000 --- a/src/store.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {createStore} from 'vuex' - -const store = createStore({ - state() { - return { - servers: [], - worlds: [], - maps: [], - players: [], - - following: null, - - currentServer: null, - currentWorld: null, - currentMap: null, - } - } -}); - -export default store; \ No newline at end of file diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..091bdf5 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,326 @@ +import { + createStore, + Store as VuexStore, + createLogger, + MutationTree, + ActionContext, ActionTree, GetterTree, CommitOptions, DispatchOptions, +} from 'vuex'; +import API from './../api'; +import { + DynmapConfigurationResponse, + DynmapMap, + DynmapMessageConfig, + DynmapPlayer, + DynmapServerConfig, + DynmapUpdateResponse, + DynmapWorld +} from "@/dynmap"; + +// Mutations +export enum MutationTypes { + SET_CONFIGURATION = 'setConfiguration', + SET_MESSAGES = 'setMessages', + SET_WORLDS = 'setWorlds', + ADD_WORLD = 'addWorld', + SET_TIME_OF_DAY = 'setTimeOfDay', + SET_RAINING = 'setRaining', + SET_THUNDERING = 'setThundering', + SET_UPDATE_TIMESTAMP = 'setUpdateTimestamp', + INCREMENT_REQUEST_ID = 'incrementRequestId', + SET_PLAYERS = 'setPlayers', + SET_CURRENT_MAP = 'setCurrentMap', +} + +export enum ActionTypes { + LOAD_CONFIGRUATION = "loadConfiguration", + GET_UPDATE = "getUpdate", +} + +export type CurrentMapPayload = { + world: string + map: string +} + +export type Mutations = { + [MutationTypes.SET_CONFIGURATION](state: S, config: DynmapServerConfig): void + [MutationTypes.SET_MESSAGES](state: S, messages: DynmapMessageConfig): void + [MutationTypes.SET_WORLDS](state: S, worlds: Array): void + [MutationTypes.ADD_WORLD](state: S, world: DynmapWorld): void + [MutationTypes.SET_TIME_OF_DAY](state: S, time: number): void + [MutationTypes.SET_RAINING](state: S, raining: boolean): void + [MutationTypes.SET_THUNDERING](state: S, thundering: boolean): void + [MutationTypes.SET_UPDATE_TIMESTAMP](state: S, time: Date): void + [MutationTypes.INCREMENT_REQUEST_ID](state: S): void + [MutationTypes.SET_PLAYERS](state: S, players: Array): void + [MutationTypes.SET_CURRENT_MAP](state: S, payload: CurrentMapPayload): void +} + +const mutations: MutationTree & Mutations = { + [MutationTypes.SET_CONFIGURATION](state: State, config: DynmapServerConfig) { + state.configuration = Object.assign(state.configuration, config); + }, + [MutationTypes.SET_MESSAGES](state: State, messages: DynmapMessageConfig) { + state.messages = Object.assign(state.messages, messages); + }, + + [MutationTypes.SET_WORLDS](state: State, worlds: Array) { + state.worlds.clear(); + state.maps.clear(); + + state.configuration.followMap = undefined; + state.configuration.followZoom = undefined; + state.configuration.defaultMap = undefined; + state.configuration.defaultWorld = undefined; + + state.currentMap = undefined; + state.currentWorld = undefined; + state.following = undefined; + + state.timeOfDay = 0; + state.raining = false; + state.thundering = false; + + worlds.forEach(world => { + state.worlds.set(world.name, world); + world.maps.forEach(map => state.maps.set([world.name, map.name].join('_'), map)); + }); + }, + + [MutationTypes.ADD_WORLD](state: State, world: DynmapWorld) { + state.worlds.set(world.name, world); + }, + + [MutationTypes.SET_TIME_OF_DAY](state: State, time: number) { + if (time < 0 || time > 24000) { + throw new RangeError("Time must be between 0 and 24000"); + } + + state.timeOfDay = time; + }, + + [MutationTypes.SET_RAINING](state: State, raining: boolean) { + state.raining = raining; + }, + + [MutationTypes.SET_THUNDERING](state: State, thundering: boolean) { + state.thundering = thundering; + }, + + [MutationTypes.SET_UPDATE_TIMESTAMP](state: State, timestamp: Date) { + state.updateTimestamp = timestamp; + }, + + [MutationTypes.INCREMENT_REQUEST_ID](state: State) { + state.updateRequestId++; + }, + + [MutationTypes.SET_PLAYERS](state: State, players: Array) { + const existingPlayers: Set = new Set(); + + players.forEach(player => { + existingPlayers.add(player.account); + + if (state.players.has(player.account)) { + const existing = state.players.get(player.account); + + existing!.health = player.health; + existing!.armor = player.armor; + existing!.location = player.location; + existing!.name = player.name; + existing!.sort = player.sort; + } else { + state.players.set(player.account, { + account: player.account, + health: player.health, + armor: player.armor, + location: player.location, + name: player.name, + sort: player.sort, + }); + } + }); + + for (const key of state.players.keys()) { + if (!existingPlayers.has(key)) { + state.players.delete(key); + } + } + }, + + [MutationTypes.SET_CURRENT_MAP](state: State, {world, map}) { + const mapName = [world, map].join('_'); + + if(!state.worlds.has(world)) { + throw new RangeError(`Unknown world ${world}`); + } + + if(!state.maps.has(mapName)) { + throw new RangeError(`Unknown map ${map}`); + } + + state.currentWorld = state.worlds.get(world); + state.currentMap = state.maps.get(mapName); + }, +} + +type AugmentedActionContext = { + commit( + key: K, + payload: Parameters[1] + ):ReturnType; +} & Omit, "commit"> + +export interface Actions { + [ActionTypes.LOAD_CONFIGRUATION]( + {commit}: AugmentedActionContext, + ):Promise + [ActionTypes.GET_UPDATE]( + {commit}: AugmentedActionContext, + ):Promise +} + +export const actions: ActionTree & Actions = { + [ActionTypes.LOAD_CONFIGRUATION]({commit}) { + return API.getConfiguration().then(config => { + commit(MutationTypes.SET_CONFIGURATION, config.config); + commit(MutationTypes.SET_MESSAGES, config.messages); + commit(MutationTypes.SET_WORLDS, config.worlds); + + if(config.config.defaultWorld && config.config.defaultMap) { + commit(MutationTypes.SET_CURRENT_MAP, { + world: config.config.defaultWorld, + map: config.config.defaultMap + }); + } + + return config; + }); + }, + [ActionTypes.GET_UPDATE]({commit}) { + if(!state.currentWorld) { + return Promise.reject("No current world"); + } + + return API.getUpdate(state.updateRequestId, state.currentWorld.name, state.updateTimestamp.getUTCMilliseconds()).then(update => { + commit(MutationTypes.SET_PLAYERS, update.players); + commit(MutationTypes.SET_TIME_OF_DAY, update.timeOfDay); + commit(MutationTypes.SET_RAINING, update.raining); + commit(MutationTypes.SET_THUNDERING, update.thundering); + commit(MutationTypes.SET_UPDATE_TIMESTAMP, new Date(update.timestamp)); + commit(MutationTypes.INCREMENT_REQUEST_ID, undefined); + + return update; + }); + } +} + +export type State = { + configuration: DynmapServerConfig; + messages: DynmapMessageConfig; + worlds: Map; + maps: Map; + players: Map; + + following?: DynmapPlayer; + + // currentServer?: string; + currentWorld?: DynmapWorld; + currentMap?: DynmapMap; + + raining: boolean; + thundering: boolean; + timeOfDay: number; + + updateRequestId: number; + updateTimestamp: Date; +} + +export type Getters = { + +} + +export const getters: GetterTree & Getters = { + +} + +export type Store = Omit< + VuexStore, + "commit" | "getters" | "dispatch" + > & { + commit[1]>( + key: K, + payload: P, + options?: CommitOptions, + ):ReturnType; +} & { + getters: { + [K in keyof Getters]: ReturnType + }; +} & { + dispatch( + key: K, + payload: Parameters[1], + options?: DispatchOptions + ):ReturnType; +}; + +const state: State = { + configuration: { + version: '', + allowChat: false, + chatRequiresLogin: false, + chatInterval: 5000, + defaultMap: '', + defaultWorld: '', + defaultZoom: 0, + followMap: '', + followZoom: 0, + updateInterval: 3000, + showLayerControl: true, + title: '', + loginEnabled: false, + loginRequired: false, + maxPlayers: 0, + hash: 0, + }, + messages: { + chatNotAllowed: '', + chatRequiresLogin: '', + chatCooldown: '', + mapTypes: '', + players: '', + playerJoin: '', + playerQuit: '', + anonymousJoin: '', + anonymousQuit: '', + }, + worlds: new Map(), + maps: new Map(), + players: new Map(), + + raining: false, + thundering: false, + timeOfDay: 0, + + following: undefined, + + // currentServer: undefined, + currentWorld: undefined, + currentMap: undefined, + + updateRequestId: 0, + updateTimestamp: new Date(), +}; + +export const store = createStore({ + state, + mutations, + getters, + actions, + // plugins: [createLogger()], +}); + +// define your own `useStore` composition function +export function useStore() { + return store as Store; +} diff --git a/src/vuex.d.ts b/src/vuex.d.ts new file mode 100644 index 0000000..8927d01 --- /dev/null +++ b/src/vuex.d.ts @@ -0,0 +1,9 @@ +import { ComponentCustomProperties } from 'vue' +import {State, Store} from "@/store"; + +declare module '@vue/runtime-core' { + // provide typings for `this.$store` + interface ComponentCustomProperties { + $store: Store + } +} \ No newline at end of file