Optimize finalized surface artwork
This commit is contained in:
parent
82938d3d57
commit
f2239d248a
14 changed files with 1254 additions and 305 deletions
|
|
@ -1,7 +1,7 @@
|
|||
class_name SurfaceDrawingProtocol
|
||||
extends RefCounted
|
||||
|
||||
const CAPABILITY: StringName = &"surface_drawing_v2"
|
||||
const CAPABILITY: StringName = &"surface_drawing_v3"
|
||||
const RELIABLE_CHANNEL: int = NetworkProtocol.DRAWING_RELIABLE_CHANNEL
|
||||
const GRID_SIZES: Array[int] = [16, 32, 64, 128]
|
||||
const DEFAULT_GRID_SIZE: int = 16
|
||||
|
|
@ -11,8 +11,12 @@ const GRID_WIDTH: int = DEFAULT_GRID_SIZE
|
|||
const GRID_HEIGHT: int = DEFAULT_GRID_SIZE
|
||||
const CELL_SIZE: float = 0.075
|
||||
const MAX_ACTIVE_CANVASES: int = 24
|
||||
const MAX_CANVASES: int = 48
|
||||
const MAX_SESSION_GRID_CELLS: int = 49152
|
||||
const MAX_FINALIZED_CANVASES: int = 512
|
||||
const MAX_CANVASES: int = MAX_ACTIVE_CANVASES + MAX_FINALIZED_CANVASES
|
||||
const MAX_ACTIVE_GRID_CELLS: int = 49152
|
||||
const MAX_FINALIZED_GRID_CELLS: int = 8 * 1024 * 1024
|
||||
# Compatibility alias for code concerned only with live editing capacity.
|
||||
const MAX_SESSION_GRID_CELLS: int = MAX_ACTIVE_GRID_CELLS
|
||||
const MAX_EDITS_PER_REQUEST: int = 16
|
||||
const MAX_CANVAS_ID_LENGTH: int = 64
|
||||
const MAX_REQUEST_ID_LENGTH: int = 64
|
||||
|
|
@ -22,6 +26,7 @@ const MAX_SESSION_ID_LENGTH: int = 96
|
|||
# for a complete room turnover while never accepting unattributed edits.
|
||||
const MAX_PARTICIPANTS: int = 256
|
||||
const MAX_COORDINATE: float = 10000.0
|
||||
const CELL_ENCODING := "palette_author_planes_v1"
|
||||
|
||||
|
||||
static func validate_canvas_request(data: Variant) -> bool:
|
||||
|
|
@ -122,59 +127,93 @@ static func validate_canvas_state(data: Variant) -> bool:
|
|||
if typeof(data) != TYPE_DICTIONARY:
|
||||
return false
|
||||
var value: Dictionary = data
|
||||
if (
|
||||
typeof(value.get("session_id")) != TYPE_STRING
|
||||
or str(value["session_id"]).is_empty()
|
||||
or str(value["session_id"]).length() > MAX_SESSION_ID_LENGTH
|
||||
or typeof(value.get("canvas_id")) != TYPE_STRING
|
||||
or str(value["canvas_id"]).is_empty()
|
||||
or str(value["canvas_id"]).length() > MAX_CANVAS_ID_LENGTH
|
||||
or not _valid_vector(value.get("origin"))
|
||||
or not _valid_vector(value.get("normal"))
|
||||
or not _valid_vector(value.get("tangent"))
|
||||
or typeof(value.get("width")) != TYPE_INT
|
||||
or int(value["width"]) not in GRID_SIZES
|
||||
or typeof(value.get("height")) != TYPE_INT
|
||||
or int(value["height"]) != int(value["width"])
|
||||
or typeof(value.get("cell_size")) not in [TYPE_FLOAT, TYPE_INT]
|
||||
or not is_equal_approx(float(value["cell_size"]), CELL_SIZE)
|
||||
or typeof(value.get("revision")) != TYPE_INT
|
||||
or int(value["revision"]) < 0
|
||||
or typeof(value.get("guide_visible", true)) != TYPE_BOOL
|
||||
or typeof(value.get("finalized", false)) != TYPE_BOOL
|
||||
or typeof(value.get("layer", 0)) != TYPE_INT
|
||||
or int(value.get("layer", 0)) < 0
|
||||
or not NetworkIdentityCrypto.valid_fingerprint(
|
||||
value.get("creator_fingerprint")
|
||||
)
|
||||
or not _valid_participant_fingerprints(
|
||||
value.get("participant_fingerprints", [])
|
||||
)
|
||||
or typeof(value.get("cells")) != TYPE_ARRAY
|
||||
):
|
||||
if not validate_canvas_metadata(value):
|
||||
return false
|
||||
var cells: Array = value["cells"]
|
||||
var grid_width: int = int(value["width"])
|
||||
var grid_height: int = int(value["height"])
|
||||
if cells.size() > grid_width * grid_height:
|
||||
return false
|
||||
for cell_value: Variant in cells:
|
||||
if (
|
||||
not validate_authoritative_cell(cell_value)
|
||||
or int((cell_value as Dictionary)["x"]) >= grid_width
|
||||
or int((cell_value as Dictionary)["y"]) >= grid_height
|
||||
):
|
||||
return false
|
||||
var participants: Array = value.get("participant_fingerprints", [])
|
||||
if not participants.is_empty():
|
||||
if str(value["creator_fingerprint"]) not in participants:
|
||||
if not participants.is_empty() and str(value["creator_fingerprint"]) not in participants:
|
||||
return false
|
||||
if typeof(value.get("cells")) == TYPE_ARRAY:
|
||||
var cells: Array = value["cells"]
|
||||
var grid_width: int = int(value["width"])
|
||||
var grid_height: int = int(value["height"])
|
||||
if cells.size() > grid_width * grid_height:
|
||||
return false
|
||||
for cell_value: Variant in cells:
|
||||
if str((cell_value as Dictionary)["author_fingerprint"]) not in participants:
|
||||
if (
|
||||
not validate_authoritative_cell(cell_value)
|
||||
or int((cell_value as Dictionary)["x"]) >= grid_width
|
||||
or int((cell_value as Dictionary)["y"]) >= grid_height
|
||||
):
|
||||
return false
|
||||
if (
|
||||
not participants.is_empty()
|
||||
and str((cell_value as Dictionary)["author_fingerprint"])
|
||||
not in participants
|
||||
):
|
||||
return false
|
||||
return true
|
||||
if (
|
||||
str(value.get("cell_encoding", "")) != CELL_ENCODING
|
||||
or typeof(value.get("cell_colors")) != TYPE_PACKED_BYTE_ARRAY
|
||||
or typeof(value.get("cell_authors")) != TYPE_PACKED_INT32_ARRAY
|
||||
or participants.is_empty()
|
||||
):
|
||||
return false
|
||||
var colors: PackedByteArray = value["cell_colors"]
|
||||
var authors: PackedInt32Array = value["cell_authors"]
|
||||
var expected_size: int = int(value["width"]) * int(value["height"])
|
||||
if colors.size() != expected_size or authors.size() != expected_size:
|
||||
return false
|
||||
for index: int in expected_size:
|
||||
var color_index: int = colors[index]
|
||||
var author_slot: int = authors[index]
|
||||
if color_index == 0:
|
||||
if author_slot != 0:
|
||||
return false
|
||||
elif (
|
||||
color_index > SurfaceDrawingPalette.COLORS.size()
|
||||
or author_slot <= 0
|
||||
or author_slot > participants.size()
|
||||
):
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
static func validate_canvas_metadata(data: Variant) -> bool:
|
||||
if typeof(data) != TYPE_DICTIONARY:
|
||||
return false
|
||||
var value: Dictionary = data
|
||||
return (
|
||||
typeof(value.get("session_id")) == TYPE_STRING
|
||||
and not str(value["session_id"]).is_empty()
|
||||
and str(value["session_id"]).length() <= MAX_SESSION_ID_LENGTH
|
||||
and typeof(value.get("canvas_id")) == TYPE_STRING
|
||||
and not str(value["canvas_id"]).is_empty()
|
||||
and str(value["canvas_id"]).length() <= MAX_CANVAS_ID_LENGTH
|
||||
and _valid_vector(value.get("origin"))
|
||||
and _valid_vector(value.get("normal"))
|
||||
and _valid_vector(value.get("tangent"))
|
||||
and typeof(value.get("width")) == TYPE_INT
|
||||
and int(value["width"]) in GRID_SIZES
|
||||
and typeof(value.get("height")) == TYPE_INT
|
||||
and int(value["height"]) == int(value["width"])
|
||||
and typeof(value.get("cell_size")) in [TYPE_FLOAT, TYPE_INT]
|
||||
and is_equal_approx(float(value["cell_size"]), CELL_SIZE)
|
||||
and typeof(value.get("revision")) == TYPE_INT
|
||||
and int(value["revision"]) >= 0
|
||||
and typeof(value.get("guide_visible", true)) == TYPE_BOOL
|
||||
and typeof(value.get("finalized", false)) == TYPE_BOOL
|
||||
and typeof(value.get("layer", 0)) == TYPE_INT
|
||||
and int(value.get("layer", 0)) >= 0
|
||||
and NetworkIdentityCrypto.valid_fingerprint(
|
||||
value.get("creator_fingerprint")
|
||||
)
|
||||
and _valid_participant_fingerprints(
|
||||
value.get("participant_fingerprints", [])
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
static func validate_guide_update(data: Variant) -> bool:
|
||||
if typeof(data) != TYPE_DICTIONARY:
|
||||
return false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue