move zoom tile creation into seperate worker thread

This commit is contained in:
HF 2022-04-04 05:07:27 +02:00
parent 12f2862769
commit 258fd42e68
8 changed files with 437 additions and 400 deletions

View File

@ -3,53 +3,53 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
#: src/core/ChatProvider.js:350
#: src/core/ChatProvider.js:370
msgid "You can not send chat messages with proxy"
msgstr ""
#: src/core/ChatProvider.js:364
#: src/core/ChatProvider.js:384
#, javascript-format
msgid "You are sending messages too fast, you have to wait ${ waitTime }s :("
msgstr ""
#: src/core/ChatProvider.js:368
#: src/core/ChatProvider.js:388
msgid "You don't have access to this channel"
msgstr ""
#: src/core/ChatProvider.js:384
#: src/core/ChatProvider.js:404
msgid "Your mail has to be verified in order to chat"
msgstr ""
#: src/core/ChatProvider.js:389
#: src/core/ChatProvider.js:409
msgid "You are permanently muted, join our guilded to apppeal the mute"
msgstr ""
#: src/core/ChatProvider.js:394
#: src/core/ChatProvider.js:414
#, javascript-format
msgid "You are muted for another ${ timeMin } minutes"
msgstr ""
#: src/core/ChatProvider.js:396
#: src/core/ChatProvider.js:416
msgid "You are muted for another ${ muted } seconds"
msgstr ""
#: src/core/ChatProvider.js:404
#: src/core/ChatProvider.js:424
msgid "Ow no! Spam protection decided to mute you"
msgstr ""
#: src/core/ChatProvider.js:415
#: src/core/ChatProvider.js:435
msgid "You can't send a message this long :("
msgstr ""
#: src/core/ChatProvider.js:419
#: src/core/ChatProvider.js:439
msgid "Please use int channel"
msgstr ""
#: src/core/ChatProvider.js:423
#: src/core/ChatProvider.js:443
msgid "Your country is temporary muted from chat"
msgstr ""
#: src/core/ChatProvider.js:431
#: src/core/ChatProvider.js:451
msgid "Stop flooding."
msgstr ""
@ -245,15 +245,15 @@ msgstr ""
msgid "Server error occured"
msgstr ""
#: src/routes/api/modtools.js:50
#: src/routes/api/modtools.js:52
msgid "You are not logged in"
msgstr ""
#: src/routes/api/modtools.js:62
#: src/routes/api/modtools.js:64
msgid "You are not allowed to access this page"
msgstr ""
#: src/routes/api/modtools.js:128
#: src/routes/api/modtools.js:166
msgid "Just admins can do that"
msgstr ""
@ -282,7 +282,7 @@ msgid "Name can't be empty."
msgstr ""
#: src/utils/validation.js:31
msgid "Name must be at least 4 characters long"
msgid "Name must be at least 2 characters long"
msgstr ""
#: src/utils/validation.js:32

View File

@ -3,6 +3,48 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
#: src/controls/keypress.js:41
#, javascript-format
msgid "Switched to ${ canvasName }"
msgstr ""
#: src/controls/keypress.js:64
msgid "Grid ON"
msgstr ""
#: src/controls/keypress.js:65
msgid "Grid OFF"
msgstr ""
#: src/controls/keypress.js:75
msgid "Pixel Notify ON"
msgstr ""
#: src/controls/keypress.js:76
msgid "Pixel Notify OFF"
msgstr ""
#: src/controls/keypress.js:81
msgid "Muted Sound"
msgstr ""
#: src/controls/keypress.js:82
msgid "Unmuted Sound"
msgstr ""
#: src/components/CoordinatesBox.jsx:29
#: src/controls/keypress.js:88
msgid "Copied!"
msgstr ""
#: src/controls/keypress.js:94
msgid "Show Hidden Canvases"
msgstr ""
#: src/controls/keypress.js:95
msgid "Hide Hidden Canvases"
msgstr ""
#: src/ui/placePixel.js:53
msgid "Error :("
msgstr ""
@ -104,48 +146,6 @@ msgstr ""
msgid "Error ${ retCode }"
msgstr ""
#: src/controls/keypress.js:41
#, javascript-format
msgid "Switched to ${ canvasName }"
msgstr ""
#: src/controls/keypress.js:64
msgid "Grid ON"
msgstr ""
#: src/controls/keypress.js:65
msgid "Grid OFF"
msgstr ""
#: src/controls/keypress.js:75
msgid "Pixel Notify ON"
msgstr ""
#: src/controls/keypress.js:76
msgid "Pixel Notify OFF"
msgstr ""
#: src/controls/keypress.js:81
msgid "Muted Sound"
msgstr ""
#: src/controls/keypress.js:82
msgid "Unmuted Sound"
msgstr ""
#: src/components/CoordinatesBox.jsx:29
#: src/controls/keypress.js:88
msgid "Copied!"
msgstr ""
#: src/controls/keypress.js:94
msgid "Show Hidden Canvases"
msgstr ""
#: src/controls/keypress.js:95
msgid "Hide Hidden Canvases"
msgstr ""
#: src/ui/renderer.js:36
msgid "Canvas Error"
msgstr ""
@ -170,6 +170,11 @@ msgstr ""
msgid "Look at past Canvases"
msgstr ""
#: src/components/Converter.jsx:559
#: src/components/CoordinatesBox.jsx:32
msgid "Copy to Clipboard"
msgstr ""
#: src/components/OnlineBox.jsx:41
msgid "Online Users on Canvas"
msgstr ""
@ -182,13 +187,8 @@ msgstr ""
msgid "Pixels placed"
msgstr ""
#: src/components/Converter.jsx:559
#: src/components/CoordinatesBox.jsx:32
msgid "Copy to Clipboard"
msgstr ""
#: src/components/ModalRoot.jsx:69
#: src/components/Modtools.jsx:224
#: src/components/Modtools.jsx:318
#: src/components/Window.jsx:138
#: src/components/contextmenus/ChannelContextMenu.jsx:67
msgid "Close"
@ -198,27 +198,6 @@ msgstr ""
msgid "Restore"
msgstr ""
#: src/components/buttons/ChatButton.jsx:92
msgid "Close Chat"
msgstr ""
#: src/components/buttons/ChatButton.jsx:92
msgid "Open Chat"
msgstr ""
#: src/components/buttons/CanvasSwitchButton.jsx:22
#: src/components/windows/index.js:19
msgid "Canvas Selection"
msgstr ""
#: src/components/buttons/ExpandMenuButton.jsx:23
msgid "Close Menu"
msgstr ""
#: src/components/buttons/ExpandMenuButton.jsx:23
msgid "Open Menu"
msgstr ""
#: src/actions/fetch.js:39
msgid "You made too many requests"
msgstr ""
@ -248,8 +227,25 @@ msgstr ""
msgid "Server answered with gibberish :("
msgstr ""
#: src/components/buttons/GlobeButton.jsx:35
msgid "Globe View"
#: src/components/buttons/ChatButton.jsx:92
msgid "Close Chat"
msgstr ""
#: src/components/buttons/ChatButton.jsx:92
msgid "Open Chat"
msgstr ""
#: src/components/buttons/CanvasSwitchButton.jsx:22
#: src/components/windows/index.js:19
msgid "Canvas Selection"
msgstr ""
#: src/components/buttons/ExpandMenuButton.jsx:23
msgid "Close Menu"
msgstr ""
#: src/components/buttons/ExpandMenuButton.jsx:23
msgid "Open Menu"
msgstr ""
#: src/components/HistorySelect.jsx:144
@ -260,33 +256,6 @@ msgstr ""
msgid "Select Date above"
msgstr ""
#: src/components/buttons/PalselButton.jsx:31
msgid "Close Palette"
msgstr ""
#: src/components/buttons/PalselButton.jsx:31
msgid "Open Palette"
msgstr ""
#: src/components/buttons/HelpButton.jsx:23
#: src/components/windows/index.js:13
msgid "Help"
msgstr ""
#: src/components/buttons/SettingsButton.jsx:23
#: src/components/windows/index.js:14
msgid "Settings"
msgstr ""
#: src/components/buttons/DownloadButton.jsx:37
msgid "Make Screenshot"
msgstr ""
#: src/components/buttons/LogInButton.jsx:23
#: src/components/windows/index.js:15
msgid "User Area"
msgstr ""
#: src/components/Window.jsx:117
msgid "Clone"
msgstr ""
@ -303,22 +272,53 @@ msgstr ""
msgid "Resize"
msgstr ""
#: src/components/contextmenus/UserContextMenu.jsx:53
msgid "Ping"
#: src/components/buttons/SettingsButton.jsx:23
#: src/components/windows/index.js:14
msgid "Settings"
msgstr ""
#: src/components/contextmenus/UserContextMenu.jsx:78
msgid "DM"
#: src/components/buttons/HelpButton.jsx:23
#: src/components/windows/index.js:13
msgid "Help"
msgstr ""
#: src/components/contextmenus/UserContextMenu.jsx:88
msgid "Block"
#: src/components/buttons/LogInButton.jsx:23
#: src/components/windows/index.js:15
msgid "User Area"
msgstr ""
#: src/components/buttons/DownloadButton.jsx:37
msgid "Make Screenshot"
msgstr ""
#: src/components/buttons/GlobeButton.jsx:35
msgid "Globe View"
msgstr ""
#: src/components/buttons/PalselButton.jsx:31
msgid "Close Palette"
msgstr ""
#: src/components/buttons/PalselButton.jsx:31
msgid "Open Palette"
msgstr ""
#: src/components/contextmenus/ChannelContextMenu.jsx:55
msgid "Mute"
msgstr ""
#: src/components/contextmenus/UserContextMenu.jsx:55
msgid "Ping"
msgstr ""
#: src/components/contextmenus/UserContextMenu.jsx:80
msgid "DM"
msgstr ""
#: src/components/contextmenus/UserContextMenu.jsx:90
msgid "Block"
msgstr ""
#: src/components/windows/index.js:16
msgid "Registration"
msgstr ""
@ -631,6 +631,73 @@ msgstr ""
msgid "Select Language"
msgstr ""
#: src/components/windows/UserArea.jsx:27
msgid "Profile"
msgstr ""
#: src/components/windows/UserArea.jsx:30
msgid "Ranking"
msgstr ""
#: src/components/windows/UserArea.jsx:33
msgid "Converter"
msgstr ""
#: src/components/windows/UserArea.jsx:39
msgid "Modtools"
msgstr ""
#: src/components/windows/UserArea.jsx:40
msgid "Loading..."
msgstr ""
#: src/components/windows/UserArea.jsx:47
msgid "Consider joining us on Guilded:"
msgstr ""
#: src/components/windows/Register.jsx:85
msgid "Register new account here"
msgstr ""
#: src/components/windows/Register.jsx:90
#: src/components/windows/Register.jsx:96
msgid "Name"
msgstr ""
#: src/components/windows/ForgotPassword.jsx:82
#: src/components/windows/Register.jsx:98
#: src/components/windows/Register.jsx:104
msgid "Email"
msgstr ""
#: src/components/ChangeMail.jsx:80
#: src/components/DeleteAccount.jsx:62
#: src/components/LogInForm.jsx:83
#: src/components/windows/Register.jsx:106
#: src/components/windows/Register.jsx:112
msgid "Password"
msgstr ""
#: src/components/windows/Register.jsx:114
#: src/components/windows/Register.jsx:120
msgid "Confirm Password"
msgstr ""
#: src/components/windows/Register.jsx:122
msgid "Captcha"
msgstr ""
#: src/components/Modtools.jsx:405
#: src/components/Modtools.jsx:486
#: src/components/Modtools.jsx:561
#: src/components/Modtools.jsx:653
#: src/components/Modtools.jsx:715
#: src/components/Modtools.jsx:798
#: src/components/windows/ForgotPassword.jsx:86
#: src/components/windows/Register.jsx:125
msgid "Submit"
msgstr ""
#: src/components/windows/CanvasSelect.jsx:33
msgid ""
"Select the canvas you want to use. Every canvas is unique and has "
@ -683,88 +750,22 @@ msgstr ""
msgid "Enter your mail address and we will send you a new password:"
msgstr ""
#: src/components/windows/ForgotPassword.jsx:82
#: src/components/windows/Register.jsx:98
#: src/components/windows/Register.jsx:104
msgid "Email"
msgstr ""
#: src/components/Modtools.jsx:311
#: src/components/Modtools.jsx:392
#: src/components/Modtools.jsx:467
#: src/components/Modtools.jsx:512
#: src/components/Modtools.jsx:595
#: src/components/windows/ForgotPassword.jsx:86
#: src/components/windows/Register.jsx:125
msgid "Submit"
msgstr ""
#: src/components/windows/Chat.jsx:146
#: src/components/windows/Chat.jsx:133
msgid "Channel settings"
msgstr ""
#: src/components/windows/Chat.jsx:161
#: src/components/windows/Chat.jsx:150
msgid "Start chatting here"
msgstr ""
#: src/components/windows/Chat.jsx:198
#: src/components/windows/Chat.jsx:192
msgid "Chat here"
msgstr ""
#: src/components/windows/Chat.jsx:221
#: src/components/windows/Chat.jsx:214
msgid "You must be logged in to chat"
msgstr ""
#: src/components/windows/UserArea.jsx:27
msgid "Profile"
msgstr ""
#: src/components/windows/UserArea.jsx:30
msgid "Ranking"
msgstr ""
#: src/components/windows/UserArea.jsx:33
msgid "Converter"
msgstr ""
#: src/components/windows/UserArea.jsx:39
msgid "Modtools"
msgstr ""
#: src/components/windows/UserArea.jsx:40
msgid "Loading..."
msgstr ""
#: src/components/windows/UserArea.jsx:47
msgid "Consider joining us on Guilded:"
msgstr ""
#: src/components/windows/Register.jsx:85
msgid "Register new account here"
msgstr ""
#: src/components/windows/Register.jsx:90
#: src/components/windows/Register.jsx:96
msgid "Name"
msgstr ""
#: src/components/ChangeMail.jsx:80
#: src/components/DeleteAccount.jsx:62
#: src/components/LogInForm.jsx:83
#: src/components/windows/Register.jsx:106
#: src/components/windows/Register.jsx:112
msgid "Password"
msgstr ""
#: src/components/windows/Register.jsx:114
#: src/components/windows/Register.jsx:120
msgid "Confirm Password"
msgstr ""
#: src/components/windows/Register.jsx:122
msgid "Captcha"
msgstr ""
#: src/components/Captcha.jsx:50
#: src/components/Captcha.jsx:105
msgid "Could not load captcha"
@ -823,7 +824,7 @@ msgid "Name can't be empty."
msgstr ""
#: src/utils/validation.js:31
msgid "Name must be at least 4 characters long"
msgid "Name must be at least 2 characters long"
msgstr ""
#: src/utils/validation.js:32
@ -853,49 +854,28 @@ msgstr ""
msgid "Save"
msgstr ""
#: src/components/CanvasItem.jsx:30
msgid "Online Users"
#: src/components/LogInArea.jsx:21
msgid "Login to access more features and stats."
msgstr ""
#: src/components/CanvasItem.jsx:35
msgid "Cooldown"
#: src/components/LogInArea.jsx:23
msgid "Login with Name or Mail:"
msgstr ""
#: src/components/CanvasItem.jsx:41
msgid "Stacking till"
#: src/components/LogInArea.jsx:30
msgid "I forgot my Password."
msgstr ""
#: src/components/CanvasItem.jsx:43
msgid "Ranked"
#: src/components/LogInArea.jsx:31
msgid "or login with:"
msgstr ""
#: src/components/CanvasItem.jsx:45
msgid "Yes"
#: src/components/LogInArea.jsx:72
msgid "or register here:"
msgstr ""
#: src/components/CanvasItem.jsx:45
msgid "No"
msgstr ""
#: src/components/CanvasItem.jsx:51
msgid "Requirements"
msgstr ""
#: src/components/CanvasItem.jsx:54
msgid "User Account"
msgstr ""
#: src/components/CanvasItem.jsx:56
#, javascript-format
msgid "and ${ canvas.req } Pixels set"
msgstr ""
#: src/components/CanvasItem.jsx:59
msgid "Top 10 Daily Ranking"
msgstr ""
#: src/components/CanvasItem.jsx:65
msgid "Dimensions"
#: src/components/LogInArea.jsx:79
msgid "Register"
msgstr ""
#: src/components/UserAreaContent.jsx:63
@ -955,81 +935,126 @@ msgstr ""
msgid "Ranking updates every 5 min. Daily rankings get reset at midnight UTC."
msgstr ""
#: src/components/Modtools.jsx:184
#: src/components/Modtools.jsx:246
msgid "Build image on canvas."
msgstr ""
#: src/components/Modtools.jsx:187
#: src/components/Modtools.jsx:249
msgid "Build image and set it to protected."
msgstr ""
#: src/components/Modtools.jsx:190
#: src/components/Modtools.jsx:252
msgid "Build image, but reset cooldown to unset-pixel cd."
msgstr ""
#: src/components/Modtools.jsx:253
#: src/components/Modtools.jsx:262
msgid "Clean spare pixels that are surrounded by unset pixels"
msgstr ""
#: src/components/Modtools.jsx:266
msgid ""
"Clean spare pixels that are surrounded by unset pixels and up to 1 other "
"set pixels"
msgstr ""
#: src/components/Modtools.jsx:270
msgid ""
"Clean spare pixels that are surrounded by a single other color or unset "
"pixels (VERY AGGRESSIVE ON CANVASES THAT ALLOW UNSET PIXELS (where there "
"are two cooldowns)!)"
msgstr ""
#: src/components/Modtools.jsx:292
msgid "Status: Not running"
msgstr ""
#: src/components/Modtools.jsx:347
msgid "Image Upload"
msgstr ""
#: src/components/Modtools.jsx:254
#: src/components/Modtools.jsx:348
msgid "Upload images to canvas"
msgstr ""
#: src/components/Modtools.jsx:256
#: src/components/Modtools.jsx:350
msgid "File"
msgstr ""
#: src/components/Modtools.jsx:276
#: src/components/Modtools.jsx:370
msgid "Coordinates in X_Y format:"
msgstr ""
#: src/components/Modtools.jsx:316
#: src/components/Modtools.jsx:410
msgid "Pixel Protection"
msgstr ""
#: src/components/Modtools.jsx:318
#: src/components/Modtools.jsx:412
msgid ""
"Set protection of areas (if you need finer grained control, "
"use protect with image upload and alpha layers)"
msgstr ""
#: src/components/Modtools.jsx:398
#: src/components/Modtools.jsx:432
#: src/components/Modtools.jsx:507
#: src/components/Modtools.jsx:591
msgid "Top-left corner"
msgstr ""
#: src/components/Modtools.jsx:450
#: src/components/Modtools.jsx:525
#: src/components/Modtools.jsx:609
msgid "Bottom-right corner"
msgstr ""
#: src/components/Modtools.jsx:492
msgid "Rollback to Date"
msgstr ""
#: src/components/Modtools.jsx:400
#: src/components/Modtools.jsx:494
msgid "Rollback an area of the canvas to a set date (00:00 UTC)"
msgstr ""
#: src/components/Modtools.jsx:475
#: src/components/Modtools.jsx:567
msgid "Canvas Cleaner"
msgstr ""
#: src/components/Modtools.jsx:569
msgid "Apply a filter to clean trash in large canvas areas."
msgstr ""
#: src/components/Modtools.jsx:671
msgid "Stop Cleaner"
msgstr ""
#: src/components/Modtools.jsx:678
msgid "IP Actions"
msgstr ""
#: src/components/Modtools.jsx:477
#: src/components/Modtools.jsx:680
msgid "Do stuff with IPs (one IP per line)"
msgstr ""
#: src/components/Modtools.jsx:516
#: src/components/Modtools.jsx:719
msgid "Manage Moderators"
msgstr ""
#: src/components/Modtools.jsx:518
#: src/components/Modtools.jsx:721
msgid "Remove Moderator"
msgstr ""
#: src/components/Modtools.jsx:550
#: src/components/Modtools.jsx:753
msgid "There are no mods"
msgstr ""
#: src/components/Modtools.jsx:555
#: src/components/Modtools.jsx:758
msgid "Assign new Mod"
msgstr ""
#: src/components/Modtools.jsx:558
#: src/components/Modtools.jsx:761
msgid "Enter UserName of new Mod"
msgstr ""
#: src/components/Modtools.jsx:567
#: src/components/Modtools.jsx:770
msgid "User Name"
msgstr ""
@ -1111,42 +1136,49 @@ msgstr ""
msgid "Download Template"
msgstr ""
#: src/components/LogInArea.jsx:21
msgid "Login to access more features and stats."
#: src/components/CanvasItem.jsx:30
msgid "Online Users"
msgstr ""
#: src/components/LogInArea.jsx:23
msgid "Login with Name or Mail:"
#: src/components/CanvasItem.jsx:35
msgid "Cooldown"
msgstr ""
#: src/components/LogInArea.jsx:30
msgid "I forgot my Password."
#: src/components/CanvasItem.jsx:41
msgid "Stacking till"
msgstr ""
#: src/components/LogInArea.jsx:31
msgid "or login with:"
#: src/components/CanvasItem.jsx:43
msgid "Ranked"
msgstr ""
#: src/components/LogInArea.jsx:72
msgid "or register here:"
#: src/components/CanvasItem.jsx:45
msgid "Yes"
msgstr ""
#: src/components/LogInArea.jsx:79
msgid "Register"
#: src/components/CanvasItem.jsx:45
msgid "No"
msgstr ""
#: src/components/UserMessages.jsx:28
msgid ""
"Please verify your mail address \n"
"or your account could get deleted after a few days."
#: src/components/CanvasItem.jsx:51
msgid "Requirements"
msgstr ""
#: src/components/UserMessages.jsx:49
msgid "A new verification mail is getting sent to you."
#: src/components/CanvasItem.jsx:54
msgid "User Account"
msgstr ""
#: src/components/UserMessages.jsx:53
msgid "Click here to request a new verification mail."
#: src/components/CanvasItem.jsx:56
#, javascript-format
msgid "and ${ canvas.req } Pixels set"
msgstr ""
#: src/components/CanvasItem.jsx:59
msgid "Top 10 Daily Ranking"
msgstr ""
#: src/components/CanvasItem.jsx:65
msgid "Dimensions"
msgstr ""
#: src/components/ChangePassword.jsx:22
@ -1173,6 +1205,28 @@ msgstr ""
msgid "New Username"
msgstr ""
#: src/components/UserMessages.jsx:28
msgid ""
"Please verify your mail address \n"
"or your account could get deleted after a few days."
msgstr ""
#: src/components/UserMessages.jsx:49
msgid "A new verification mail is getting sent to you."
msgstr ""
#: src/components/UserMessages.jsx:53
msgid "Click here to request a new verification mail."
msgstr ""
#: src/components/LogInForm.jsx:76
msgid "Name or Email"
msgstr ""
#: src/components/LogInForm.jsx:87
msgid "LogIn"
msgstr ""
#: src/components/ChangeMail.jsx:59
msgid ""
"Changed Mail successfully. We sent you a verification mail, "
@ -1183,6 +1237,10 @@ msgstr ""
msgid "New Mail"
msgstr ""
#: src/components/DeleteAccount.jsx:66
msgid "Yes, Delete My Account!"
msgstr ""
#: src/components/SocialSettings.jsx:38
msgid "Block all Private Messages"
msgstr ""
@ -1195,18 +1253,6 @@ msgstr ""
msgid "You have no users blocked"
msgstr ""
#: src/components/DeleteAccount.jsx:66
msgid "Yes, Delete My Account!"
msgstr ""
#: src/components/LogInForm.jsx:76
msgid "Name or Email"
msgstr ""
#: src/components/LogInForm.jsx:87
msgid "LogIn"
msgstr ""
#: src/components/windows/Help.jsx:14
#: src/components/windows/Settings.jsx:134
msgctxt "keybinds"

View File

@ -1,14 +1,17 @@
/*
* * basic functions for creating zommed tiles
* basic functions for creating zommed tiles
* Used by tilewriter worker thread, so dont import too much.
*
* */
/* eslint-disable no-console */
// Tile creation is allowed to be slow
/* eslint-disable no-await-in-loop */
import sharp from 'sharp';
import fs from 'fs';
import logger from './logger';
import { getMaxTiledZoom } from './utils';
import { TILE_SIZE, TILE_ZOOM_LEVEL } from './constants';
@ -171,7 +174,7 @@ export async function createZoomTileFromChunk(
.resize(TILE_SIZE)
.png({ options: { compressionLevel: 6 } })
.toFile(filename);
logger.info(
console.log(
// eslint-disable-next-line max-len
`Tiling: Created Tile ${filename} with ${na.length} empty chunks in ${Date.now() - startTime}ms`,
);
@ -228,7 +231,7 @@ export async function createZoomedTile(
},
},
).resize(TILE_SIZE).toFile(filename);
logger.info(
console.log(
// eslint-disable-next-line max-len
`Tiling: Created tile ${filename} with ${na.length} empty subtiles in ${Date.now() - startTime}ms.`,
);
@ -269,7 +272,7 @@ export async function createEmptyTile(
})
.png({ options: { compressionLevel: 6 } })
.toFile(filename);
logger.info(`Tiling: Created empty tile at ${filename}`);
console.log(`Tiling: Created empty tile at ${filename}`);
}
/*
@ -343,7 +346,7 @@ export async function createTexture(
},
},
).toFile(filename);
logger.info(
console.log(
`Tiling: Created texture in ${(Date.now() - startTime) / 1000}s.`,
);
}
@ -365,7 +368,7 @@ export async function initializeTiles(
palette,
force: boolean = false,
) {
logger.info(
console.log(
`Tiling: Initializing tiles in ${canvasTileFolder}, forceint = ${force}`,
);
const startTime = Date.now();
@ -375,7 +378,7 @@ export async function initializeTiles(
// base zoomlevel
let zoom = maxTiledZoom - 1;
let zoomDir = `${canvasTileFolder}/${zoom}`;
logger.info(`Tiling: Checking zoomlevel ${zoomDir}`);
console.log(`Tiling: Checking zoomlevel ${zoomDir}`);
if (!fs.existsSync(zoomDir)) fs.mkdirSync(zoomDir);
let cnt = 0;
let cnts = 0;
@ -399,7 +402,7 @@ export async function initializeTiles(
}
}
}
logger.info(
console.log(
`Tiling: Created ${cnts} / ${cnt} tiles for basezoom of canvas${canvasId}`,
);
// zoomlevels that are created from other zoomlevels
@ -407,7 +410,7 @@ export async function initializeTiles(
cnt = 0;
cnts = 0;
zoomDir = `${canvasTileFolder}/${zoom}`;
logger.info(`Tiling: Checking zoomlevel ${zoomDir}`);
console.log(`Tiling: Checking zoomlevel ${zoomDir}`);
if (!fs.existsSync(zoomDir)) fs.mkdirSync(zoomDir);
const maxZ = TILE_ZOOM_LEVEL ** zoom;
for (let cx = 0; cx < maxZ; cx += 1) {
@ -426,7 +429,7 @@ export async function initializeTiles(
}
}
}
logger.info(
console.log(
// eslint-disable-next-line max-len
`Tiling: Created ${cnts} / ${cnt} tiles for zoom ${zoom} for canvas${canvasId}`,
);
@ -440,7 +443,7 @@ export async function initializeTiles(
palette,
);
//--
logger.info(
console.log(
// eslint-disable-next-line max-len
`Tiling: Elapsed Time: ${Math.round((Date.now() - startTime) / 1000)} for canvas${canvasId}`,
);

View File

@ -1,9 +1,7 @@
/*
* draw pixel on canvas
*/
import { using } from 'bluebird';
import { redlock } from '../data/redis';
import {
getPixelFromChunkOffset,
} from './utils';
@ -375,76 +373,3 @@ export async function drawByCoords(
coolDownSeconds: coolDown / 1000,
};
}
/**
* This function is a wrapper for draw. It fixes race condition exploits
* It permits just placing one pixel at a time per user.
*
* @param user
* @param canvasId
* @param color
* @param x
* @param y
* @param z (optional for 3d canvas)
*/
export function drawSafeByCoords(
user,
canvasId,
color,
x,
y,
z = null,
) {
// can just check for one unique occurence,
// we use ip, because id for logged out users is
// always null
const userId = user.ip;
return new Promise((resolve) => {
using(
redlock.disposer(`locks:${userId}`, 5000, logger.error),
async () => {
const ret = await drawByCoords(user, canvasId, color, x, y, z);
resolve(ret);
},
); // <-- unlock is automatically handled by bluebird
});
}
/**
* This function is a wrapper for draw. It fixes race condition exploits
* It permits just placing one pixel at a time per user.
*
* @param user
* @param canvasId
* @param i Chunk coordinates
* @param j
* @param pixels Array of indiviual pixels within the chunk, with:
* [[offset, color], [offset2, color2],...]
* Offset is the offset of the pixel within the chunk
* @return Promise<Object>
*/
export function drawSafeByOffsets(
user,
canvasId,
i,
j,
pixels,
) {
// can just check for one unique occurence,
// we use ip, because id for logged out users is
// always null
const userId = user.ip;
return new Promise((resolve) => {
using(
redlock.disposer(`locks:${userId}`, 5000, logger.error),
async () => {
const ret = await drawByOffsets(user, canvasId, i, j, pixels);
resolve(ret);
},
); // <-- unlock is automatically handled by bluebird
});
}

View File

@ -1,5 +1,5 @@
/*
* creation of tiles
* creation of zoom tiles
*
*/
@ -16,18 +16,16 @@ import {
TILE_SIZE,
TILE_ZOOM_LEVEL,
} from './constants';
import {
createZoomTileFromChunk,
createZoomedTile,
createTexture,
initializeTiles,
} from './Tile';
import { mod, getMaxTiledZoom } from './utils';
// Array that holds cells of all changed base zoomlevel tiles
const CanvasUpdaters = {};
/*
* worker thread
*/
const worker = new Worker('./workers/tilewriter.js');
class CanvasUpdater {
TileLoadingQueues;
palette;
@ -63,30 +61,37 @@ class CanvasUpdater {
const cy = Math.floor(tile / width);
if (zoom === this.maxTiledZoom - 1) {
await createZoomTileFromChunk(
RedisCanvas,
this.canvas.size,
this.id,
this.canvasTileFolder,
this.palette,
[cx, cy],
);
worker.postMessage({
task: 'createZoomTileFromChunk',
args: [
this.canvas.size,
this.id,
this.canvasTileFolder,
this.palette,
[cx, cy],
],
});
} else if (zoom !== this.maxTiledZoom) {
await createZoomedTile(
this.canvasTileFolder,
this.palette,
[zoom, cx, cy],
);
worker.postMessage({
task: 'createZoomedTile',
args: [
this.canvasTileFolder,
this.palette,
[zoom, cx, cy],
],
});
}
if (zoom === 0) {
createTexture(
RedisCanvas,
this.id,
this.canvas.size,
this.canvasTileFolder,
this.palette,
);
worker.postMessage({
task: 'createTexture',
args: [
this.id,
this.canvas.size,
this.canvasTileFolder,
this.palette,
],
});
} else {
const [ucx, ucy] = [cx, cy].map((z) => Math.floor(z / 4));
const upperTile = ucx + ucy * (TILE_ZOOM_LEVEL ** (zoom - 1));
@ -115,6 +120,28 @@ class CanvasUpdater {
);
}
initializeTiles() {
return new Promise((resolve) => {
worker.postMessage({
task: 'initializeTiles',
args: [
this.canvas.size,
this.id,
this.canvasTileFolder,
this.palette,
false,
],
});
worker.once('message', (msg) => {
logger.info(
// eslint-disable-next-line max-len
`Tiling: Worker thread finished initializing Tiles with message ${msg}`,
);
resolve();
});
});
}
/*
* initialize queues and start loops for updating tiles
*/
@ -127,14 +154,7 @@ class CanvasUpdater {
logger.warn(
'Tiling: tiledir empty, will initialize it, this can take some time',
);
await initializeTiles(
RedisCanvas,
this.canvas.size,
this.id,
this.canvasTileFolder,
this.palette,
false,
);
await this.initializeTiles();
}
for (let c = 0; c < this.maxTiledZoom; c += 1) {
this.TileLoadingQueues.push([]);

View File

@ -8,7 +8,6 @@ import {
} from '../../core/constants';
// eslint-disable-next-line import/no-unresolved
import canvases from './canvases.json';
import logger from '../../core/logger';
import redis from '../redis';
@ -48,7 +47,8 @@ class RedisCanvas {
static async setChunk(i: number, j: number, chunk: Uint8Array,
canvasId: number) {
if (chunk.length !== TILE_SIZE * TILE_SIZE) {
logger.error(`Tried to set chunk with invalid length ${chunk.length}!`);
// eslint-disable-next-line no-console
console.error(`Tried to set chunk with invalid length ${chunk.length}!`);
return false;
}
const key = `ch:${canvasId}:${i}:${j}`;

42
src/workers/tilewriter.js Normal file
View File

@ -0,0 +1,42 @@
/*
* worker thread for ..core/tileserver.js
*/
/* eslint-disable no-console */
import { isMainThread, parentPort } from 'worker_threads';
import RedisCanvas from '../data/models/RedisCanvas';
import {
createZoomTileFromChunk,
createZoomedTile,
createTexture,
initializeTiles,
} from '../core/Tile';
if (isMainThread) {
throw new Error(
'Tilewriter is run as a worker thread, not as own process',
);
}
parentPort.on('message', async (msg) => {
const { task, args } = msg;
switch (task) {
case 'createZoomTileFromChunk':
createZoomTileFromChunk(RedisCanvas, ...args);
break;
case 'createZoomedTile':
createZoomedTile(...args);
break;
case 'createTexture':
createTexture(RedisCanvas, ...args);
break;
case 'initializeTiles':
await initializeTiles(RedisCanvas, ...args);
parentPort.postMessage('Done!');
break;
default:
console.warn(`Tiling: Main thread requested unknown task ${task}`);
}
});

View File

@ -51,6 +51,7 @@ export default ({
entry: {
server: [path.resolve(__dirname, 'src', 'server.js')],
backup: [path.resolve(__dirname, 'src', 'backup.js')],
'workers/tilewriter': [path.resolve(__dirname, 'src', 'workers', 'tilewriter.js')],
captchaserver: [path.resolve(__dirname, 'src', 'captchaserver.js')],
},