add map emojis to World & Europe. Leaderboard uses twemojies

This commit is contained in:
Evan
2024-10-31 16:49:40 -07:00
parent 4a3131d382
commit d08d0c473f
7 changed files with 207 additions and 82 deletions
+1 -1
View File
@@ -168,7 +168,7 @@
* implement private game DONE 10/15/2024
* private game can select map DONE 10/16/2024
* Test on android DONE 10/17/2024
* add troop max
* add troop max DONE 10/31/2024
* use twitter emojis
* create build menu
* NPC has relations
+100 -8
View File
@@ -7,17 +7,20 @@
"name": "warfront-client",
"dependencies": {
"@datastructures-js/priority-queue": "^6.3.1",
"@types/dompurify": "^3.0.5",
"@types/express": "^4.17.21",
"@types/google-protobuf": "^3.15.12",
"@types/hammerjs": "^2.0.45",
"@types/jimp": "^0.2.28",
"@types/msgpack5": "^3.4.6",
"@types/raphael": "^2.3.9",
"@types/twemoji": "^13.1.1",
"binary-loader": "^0.0.1",
"colord": "^2.9.3",
"crypto": "^1.0.1",
"d3": "^7.9.0",
"express": "^4.19.2",
"dompurify": "^3.1.7",
"express": "^4.21.1",
"google-auth-library": "^9.14.0",
"googleapis": "^143.0.0",
"hammerjs": "^2.0.8",
@@ -30,6 +33,7 @@
"protobufjs": "^7.3.2",
"pureimage": "^0.4.13",
"raphael": "^2.3.0",
"twemoji": "^14.0.2",
"uuid": "^10.0.0",
"wheelnav": "^1.7.1",
"ws": "^8.18.0",
@@ -4226,6 +4230,15 @@
"@types/d3-selection": "*"
}
},
"node_modules/@types/dompurify": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz",
"integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==",
"license": "MIT",
"dependencies": {
"@types/trusted-types": "*"
}
},
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
@@ -4237,6 +4250,7 @@
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
"license": "MIT",
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
@@ -4576,6 +4590,15 @@
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT"
},
"node_modules/@types/twemoji": {
"version": "13.1.1",
"resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-13.1.1.tgz",
"integrity": "sha512-0qnUqLhaSSGsvLXiwWnmcuOza9oGnGwXpxXauB6rEHsU30Dfmvizzwx2TzwUjlsY4ox+39tdG89CpJ/i3J/Cvw==",
"license": "MIT",
"dependencies": {
"twemoji": "*"
}
},
"node_modules/@types/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
@@ -6034,9 +6057,10 @@
"license": "MIT"
},
"node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -6881,6 +6905,12 @@
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/dompurify": {
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz",
"integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==",
"license": "(MPL-2.0 OR Apache-2.0)"
},
"node_modules/domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
@@ -7314,9 +7344,9 @@
"integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw=="
},
"node_modules/express": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
"license": "MIT",
"dependencies": {
"accepts": "~1.3.8",
@@ -7324,7 +7354,7 @@
"body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.6.0",
"cookie": "0.7.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -7584,6 +7614,29 @@
"node": ">= 0.6"
}
},
"node_modules/fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"engines": {
"node": ">=6 <7 || >=8"
}
},
"node_modules/fs-extra/node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
"license": "MIT",
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/fs-minipass": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
@@ -9785,6 +9838,18 @@
"node": ">=6"
}
},
"node_modules/jsonfile": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz",
"integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==",
"license": "MIT",
"dependencies": {
"universalify": "^0.1.2"
},
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/just-extend": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz",
@@ -13244,6 +13309,24 @@
"fsevents": "~2.3.3"
}
},
"node_modules/twemoji": {
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-14.0.2.tgz",
"integrity": "sha512-BzOoXIe1QVdmsUmZ54xbEH+8AgtOKUiG53zO5vVP2iUu6h5u9lN15NcuS6te4OY96qx0H7JK9vjjl9WQbkTRuA==",
"license": "MIT",
"dependencies": {
"fs-extra": "^8.0.1",
"jsonfile": "^5.0.0",
"twemoji-parser": "14.0.0",
"universalify": "^0.1.2"
}
},
"node_modules/twemoji-parser": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-14.0.0.tgz",
"integrity": "sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA==",
"license": "MIT"
},
"node_modules/type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
@@ -13364,6 +13447,15 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"license": "MIT",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+5 -1
View File
@@ -54,17 +54,20 @@
},
"dependencies": {
"@datastructures-js/priority-queue": "^6.3.1",
"@types/dompurify": "^3.0.5",
"@types/express": "^4.17.21",
"@types/google-protobuf": "^3.15.12",
"@types/hammerjs": "^2.0.45",
"@types/jimp": "^0.2.28",
"@types/msgpack5": "^3.4.6",
"@types/raphael": "^2.3.9",
"@types/twemoji": "^13.1.1",
"binary-loader": "^0.0.1",
"colord": "^2.9.3",
"crypto": "^1.0.1",
"d3": "^7.9.0",
"express": "^4.19.2",
"dompurify": "^3.1.7",
"express": "^4.21.1",
"google-auth-library": "^9.14.0",
"googleapis": "^143.0.0",
"hammerjs": "^2.0.8",
@@ -77,6 +80,7 @@
"protobufjs": "^7.3.2",
"pureimage": "^0.4.13",
"raphael": "^2.3.0",
"twemoji": "^14.0.2",
"uuid": "^10.0.0",
"wheelnav": "^1.7.1",
"ws": "^8.18.0",
+22 -22
View File
@@ -8,7 +8,7 @@
171,
171
],
"name": "Iceland",
"name": "Iceland 🇮🇸",
"strength": 1
},
{
@@ -16,7 +16,7 @@
477,
473
],
"name": "Ireland",
"name": "Ireland 🇮🇪",
"strength": 1
},
{
@@ -24,7 +24,7 @@
650,
500
],
"name": "England",
"name": "England 🏴󠁧󠁢󠁥󠁮󠁧󠁿",
"strength": 3
},
{
@@ -32,7 +32,7 @@
560,
800
],
"name": "Spain",
"name": "Spain 🇪🇸",
"strength": 2
},
{
@@ -40,7 +40,7 @@
726,
616
],
"name": "France",
"name": "France 🇫🇷",
"strength": 2
},
{
@@ -48,7 +48,7 @@
1050,
745
],
"name": "Italy",
"name": "Italy 🇮🇹",
"strength": 1
},
{
@@ -56,7 +56,7 @@
872,
634
],
"name": "Switzerland",
"name": "Switzerland 🇨🇭",
"strength": 1
},
{
@@ -64,7 +64,7 @@
960,
271
],
"name": "Norway",
"name": "Norway 🇳🇴",
"strength": 1
},
{
@@ -72,7 +72,7 @@
1095,
336
],
"name": "Sweden",
"name": "Sweden 🇸🇪",
"strength": 1
},
{
@@ -80,7 +80,7 @@
1403,
235
],
"name": "Finland",
"name": "Finland 🇫🇮",
"strength": 1
},
{
@@ -88,7 +88,7 @@
775,
541
],
"name": "Belgium",
"name": "Belgium 🇧🇪",
"strength": 1
},
{
@@ -96,7 +96,7 @@
868,
487
],
"name": "Netherlands",
"name": "Netherlands 🇳🇱",
"strength": 1
},
{
@@ -104,7 +104,7 @@
949,
548
],
"name": "Germany",
"name": "Germany 🇩🇪",
"strength": 1
},
{
@@ -112,7 +112,7 @@
1017,
628
],
"name": "Austria",
"name": "Austria 🇦🇹",
"strength": 1
},
{
@@ -120,7 +120,7 @@
1120,
477
],
"name": "Poland",
"name": "Poland 🇵🇱",
"strength": 1
},
{
@@ -128,7 +128,7 @@
1030,
589
],
"name": "Czechia",
"name": "Czechia 🇨🇿",
"strength": 1
},
{
@@ -136,7 +136,7 @@
1540,
602
],
"name": "Ukraine",
"name": "Ukraine 🇺🇦",
"strength": 1
},
{
@@ -144,7 +144,7 @@
1500,
440
],
"name": "Belarus",
"name": "Belarus 🇧🇾",
"strength": 1
},
{
@@ -152,7 +152,7 @@
1424,
754
],
"name": "Romania",
"name": "Romania 🇷🇴",
"strength": 1
},
{
@@ -160,7 +160,7 @@
1580,
834
],
"name": "Turkiye",
"name": "Turkiye 🇹🇷",
"strength": 1
},
{
@@ -168,7 +168,7 @@
525,
955
],
"name": "Morocco",
"name": "Morocco 🇲🇦",
"strength": 1
},
{
@@ -176,7 +176,7 @@
1674,
449
],
"name": "Russia",
"name": "Russia 🇷🇺",
"strength": 3
}
]
+44 -44
View File
@@ -8,7 +8,7 @@
375,
272
],
"name": "USA",
"name": "USA 🇺🇸",
"strength": 3
},
{
@@ -16,7 +16,7 @@
372,
136
],
"name": "Canada",
"name": "Canada 🇨🇦",
"strength": 2
},
{
@@ -24,7 +24,7 @@
375,
374
],
"name": "Mexico",
"name": "Mexico 🇲🇽",
"strength": 1
},
{
@@ -32,7 +32,7 @@
500,
378
],
"name": "Cuba",
"name": "Cuba 🇨🇺",
"strength": 1
},
{
@@ -40,7 +40,7 @@
524,
474
],
"name": "Columbia",
"name": "Columbia 🇨🇴",
"strength": 1
},
{
@@ -48,7 +48,7 @@
593,
473
],
"name": "Venezuala",
"name": "Venezuala 🇻🇪",
"strength": 1
},
{
@@ -56,7 +56,7 @@
596,
705
],
"name": "Argentina",
"name": "Argentina 🇦🇷",
"strength": 1
},
{
@@ -64,7 +64,7 @@
637,
567
],
"name": "Brazil",
"name": "Brazil 🇧🇷",
"strength": 1
},
{
@@ -72,7 +72,7 @@
1280,
975
],
"name": "Antartica",
"name": "Antartica 🇦🇶",
"strength": 3
},
{
@@ -80,7 +80,7 @@
709,
57
],
"name": "Greenland",
"name": "Greenland 🇬🇱",
"strength": 2
},
{
@@ -88,7 +88,7 @@
831,
112
],
"name": "Iceland",
"name": "Iceland 🇮🇸",
"strength": 1
},
{
@@ -96,7 +96,7 @@
925,
186
],
"name": "England",
"name": "England 🏴󠁧󠁢󠁥󠁮󠁧󠁿",
"strength": 3
},
{
@@ -104,7 +104,7 @@
887,
183
],
"name": "Ireland",
"name": "Ireland 🇮🇪",
"strength": 1
},
{
@@ -112,7 +112,7 @@
908,
264
],
"name": "Spain",
"name": "Spain 🇪🇸",
"strength": 1
},
{
@@ -120,7 +120,7 @@
1004,
250
],
"name": "Italy",
"name": "Italy 🇮🇹",
"strength": 1
},
{
@@ -128,7 +128,7 @@
958,
220
],
"name": "France",
"name": "France 🇫🇷",
"strength": 2
},
{
@@ -136,7 +136,7 @@
997,
205
],
"name": "Germany",
"name": "Germany 🇩🇪",
"strength": 1
},
{
@@ -144,7 +144,7 @@
1064,
101
],
"name": "Sweden",
"name": "Sweden 🇸🇪",
"strength": 1
},
{
@@ -152,7 +152,7 @@
1046,
193
],
"name": "Poland",
"name": "Poland 🇵🇱",
"strength": 1
},
{
@@ -160,7 +160,7 @@
1061,
188
],
"name": "Belarus",
"name": "Belarus 🇧🇾",
"strength": 1
},
{
@@ -168,7 +168,7 @@
1073,
243
],
"name": "Romania",
"name": "Romania 🇷🇴",
"strength": 1
},
{
@@ -176,7 +176,7 @@
1161,
274
],
"name": "Turkiye",
"name": "Turkiye 🇹🇷",
"strength": 1
},
{
@@ -184,7 +184,7 @@
969,
133
],
"name": "Norway",
"name": "Norway 🇳🇴",
"strength": 1
},
{
@@ -192,7 +192,7 @@
1062,
133
],
"name": "Finland",
"name": "Finland 🇫🇮",
"strength": 1
},
{
@@ -200,7 +200,7 @@
1099,
211
],
"name": "Ukraine",
"name": "Ukraine 🇺🇦",
"strength": 1
},
{
@@ -208,7 +208,7 @@
1344,
136
],
"name": "Russia",
"name": "Russia 🇷🇺",
"strength": 3
},
{
@@ -216,7 +216,7 @@
1537,
186
],
"name": "Mongolia",
"name": "Mongolia 🇲🇳",
"strength": 1
},
{
@@ -224,7 +224,7 @@
1524,
328
],
"name": "China",
"name": "China 🇨🇳",
"strength": 3
},
{
@@ -232,7 +232,7 @@
1368,
373
],
"name": "India",
"name": "India 🇮🇳",
"strength": 2
},
{
@@ -240,7 +240,7 @@
1276,
239
],
"name": "Kazakhstan",
"name": "Kazakhstan 🇰🇿",
"strength": 1
},
{
@@ -248,7 +248,7 @@
1238,
309
],
"name": "Iran",
"name": "Iran 🇮🇷",
"strength": 1
},
{
@@ -256,7 +256,7 @@
1178,
351
],
"name": "Saudi Arabia",
"name": "Saudi Arabia 🇸🇦",
"strength": 1
},
{
@@ -264,7 +264,7 @@
1679,
657
],
"name": "Australia",
"name": "Australia 🇦🇺",
"strength": 2
},
{
@@ -272,7 +272,7 @@
1890,
775
],
"name": "New Zealand",
"name": "New Zealand 🇳🇿",
"strength": 0.5
},
{
@@ -280,7 +280,7 @@
918,
342
],
"name": "Algeria",
"name": "Algeria 🇩🇿",
"strength": 1
},
{
@@ -288,7 +288,7 @@
1030,
332
],
"name": "Libya",
"name": "Libya 🇱🇾",
"strength": 1
},
{
@@ -296,7 +296,7 @@
1092,
335
],
"name": "Egypt",
"name": "Egypt 🇪🇬",
"strength": 1
},
{
@@ -304,7 +304,7 @@
963,
410
],
"name": "Niger",
"name": "Niger 🇳🇪",
"strength": 1
},
{
@@ -312,7 +312,7 @@
1112,
406
],
"name": "Sudan",
"name": "Sudan 🇸🇩",
"strength": 1
},
{
@@ -320,7 +320,7 @@
1074,
508
],
"name": "DRC",
"name": "DRC 🇨🇩",
"strength": 1
},
{
@@ -328,7 +328,7 @@
1154,
443
],
"name": "Ethiopia",
"name": "Ethiopia 🇪🇹",
"strength": 1
},
{
@@ -336,7 +336,7 @@
1075,
707
],
"name": "South Africa",
"name": "South Africa 🇿🇦",
"strength": 1
},
{
@@ -344,7 +344,7 @@
1194,
627
],
"name": "Madagascar",
"name": "Madagascar 🇲🇬",
"strength": 0.5
},
{
@@ -352,7 +352,7 @@
1052,
420
],
"name": "Chad",
"name": "Chad 🇹🇩",
"strength": 1
}
]
+21
View File
@@ -1,3 +1,6 @@
import twemoji from 'twemoji';
import DOMPurify from 'dompurify';
export function renderTroops(troops: number): string {
let troopsStr = ''
@@ -29,3 +32,21 @@ export function createCanvas(): HTMLCanvasElement {
return canvas
}
export function processName(name: string): string {
const sanitized = Array.from(name).slice(0, 10).join('').replace(/[^\p{L}\p{N}\s\p{Emoji}\p{Emoji_Component}]/gu, '');
// First sanitize the raw input - strip everything except text and emojis
const withEmojis = twemoji.parse(sanitized, {
base: 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/', // Use jsDelivr CDN
folder: 'svg', // or 'png' if you prefer
ext: '.svg' // or '.png' if you prefer
});
return DOMPurify.sanitize(withEmojis, {
ALLOWED_TAGS: ['img'],
ALLOWED_ATTR: ['src', 'alt', 'class'],
// Only allow twemoji CDN URLs
ALLOWED_URI_REGEXP: /^https:\/\/cdn\.jsdelivr\.net\/gh\/twitter\/twemoji/
});
}
+14 -6
View File
@@ -1,8 +1,12 @@
import {LitElement, html, css} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {Layer} from './Layer';
import {Game, Player} from '../../../core/game/Game';
import {ClientID} from '../../../core/Schemas';
import { LitElement, html, css } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { Layer } from './Layer';
import { Game, Player } from '../../../core/game/Game';
import { ClientID } from '../../../core/Schemas';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { processName } from '../Utils';
interface Entry {
name: string
@@ -85,6 +89,10 @@ export class Leaderboard extends LitElement implements Layer {
:host {
display: block;
}
img.emoji {
height: 1em; // Match text height
width: auto; // Maintain aspect ratio
}
.leaderboard {
position: fixed;
top: 10px;
@@ -158,7 +166,7 @@ export class Leaderboard extends LitElement implements Layer {
.map((player, index) => html`
<tr class="${player.isMyPlayer ? 'myPlayer' : 'otherPlayer'}">
<td>${player.position}</td>
<td>${player.name.slice(0, 10)}</td>
<td>${unsafeHTML(processName(player.name))}</td>
<td>${player.score}</td>
</tr>
`)}