142 lines
4.2 KiB
GDScript
142 lines
4.2 KiB
GDScript
class_name NetworkFishingProtocol
|
|
extends RefCounted
|
|
|
|
const MAX_ID_LENGTH: int = 96
|
|
const MAX_EVIDENCE_FISH_IDS: int = 256
|
|
const MAX_CAST_DISTANCE: float = 30.0
|
|
const MAX_REEL_SPEED: float = 10.0
|
|
const MAX_BARRIER_DAMAGE: int = 100
|
|
const INPUT_CHANNEL: int = 3
|
|
const SNAPSHOT_CHANNEL: int = 4
|
|
const INPUT_RATE: float = 1.0 / 30.0
|
|
const SNAPSHOT_RATE: float = 1.0 / 20.0
|
|
|
|
enum Outcome {
|
|
CATCH,
|
|
ESCAPE,
|
|
CANCELLED,
|
|
}
|
|
|
|
|
|
static func validate_cast_request(data: Variant) -> String:
|
|
if typeof(data) != TYPE_DICTIONARY:
|
|
return "Malformed fishing request."
|
|
var payload: Dictionary = data
|
|
for key: String in [
|
|
"request_id",
|
|
"session_id",
|
|
"origin",
|
|
"target",
|
|
"charge",
|
|
"rod_id",
|
|
"reel_speed",
|
|
"barrier_damage",
|
|
"bite_multiplier",
|
|
"rarity_multipliers",
|
|
"discovered_fish_ids",
|
|
"capacity_available",
|
|
]:
|
|
if not payload.has(key):
|
|
return "Malformed fishing request."
|
|
if (
|
|
typeof(payload["request_id"]) != TYPE_STRING
|
|
or typeof(payload["session_id"]) != TYPE_STRING
|
|
or typeof(payload["origin"]) != TYPE_ARRAY
|
|
or typeof(payload["target"]) != TYPE_ARRAY
|
|
or typeof(payload["charge"]) not in [TYPE_FLOAT, TYPE_INT]
|
|
or typeof(payload["rod_id"]) not in [TYPE_STRING, TYPE_STRING_NAME]
|
|
or typeof(payload["reel_speed"]) not in [TYPE_FLOAT, TYPE_INT]
|
|
or typeof(payload["barrier_damage"]) != TYPE_INT
|
|
or typeof(payload["bite_multiplier"]) not in [TYPE_FLOAT, TYPE_INT]
|
|
or typeof(payload["rarity_multipliers"]) != TYPE_ARRAY
|
|
or typeof(payload["discovered_fish_ids"]) != TYPE_ARRAY
|
|
or typeof(payload["capacity_available"]) != TYPE_BOOL
|
|
):
|
|
return "Malformed fishing request."
|
|
var request_id: String = payload["request_id"]
|
|
var session_id: String = payload["session_id"]
|
|
var origin: Array = payload["origin"]
|
|
var target: Array = payload["target"]
|
|
var charge: float = float(payload["charge"])
|
|
var reel_speed: float = float(payload["reel_speed"])
|
|
var barrier_damage: int = payload["barrier_damage"]
|
|
var bite_multiplier: float = float(payload["bite_multiplier"])
|
|
var rarity: Array = payload["rarity_multipliers"]
|
|
var discovered: Array = payload["discovered_fish_ids"]
|
|
if (
|
|
request_id.is_empty()
|
|
or request_id.length() > MAX_ID_LENGTH
|
|
or session_id.is_empty()
|
|
or session_id.length() > MAX_ID_LENGTH
|
|
or origin.size() != 3
|
|
or target.size() != 3
|
|
or not _array_is_finite_vector3(origin)
|
|
or not _array_is_finite_vector3(target)
|
|
or not is_finite(charge)
|
|
or charge < 0.0
|
|
or charge > 1.01
|
|
or not is_finite(reel_speed)
|
|
or reel_speed <= 0.0
|
|
or reel_speed > MAX_REEL_SPEED
|
|
or barrier_damage < 1
|
|
or barrier_damage > MAX_BARRIER_DAMAGE
|
|
or not is_finite(bite_multiplier)
|
|
or bite_multiplier < 0.1
|
|
or bite_multiplier > 10.0
|
|
or rarity.size() > 16
|
|
or discovered.size() > MAX_EVIDENCE_FISH_IDS
|
|
or str(payload["rod_id"]).is_empty()
|
|
or str(payload["rod_id"]).length() > 96
|
|
):
|
|
return "Fishing request values are outside allowed limits."
|
|
for value: Variant in rarity:
|
|
if (
|
|
typeof(value) not in [TYPE_FLOAT, TYPE_INT]
|
|
or not is_finite(float(value))
|
|
or float(value) < 0.0
|
|
or float(value) > 10.0
|
|
):
|
|
return "Fishing rarity evidence is invalid."
|
|
for value: Variant in discovered:
|
|
if (
|
|
typeof(value) not in [TYPE_STRING, TYPE_STRING_NAME]
|
|
or str(value).is_empty()
|
|
or str(value).length() > 96
|
|
):
|
|
return "Fishing discovery evidence is invalid."
|
|
return ""
|
|
|
|
|
|
static func validate_input(data: Variant) -> bool:
|
|
if typeof(data) != TYPE_DICTIONARY:
|
|
return false
|
|
var payload: Dictionary = data
|
|
return (
|
|
typeof(payload.get("attempt_id")) == TYPE_STRING
|
|
and not str(payload["attempt_id"]).is_empty()
|
|
and str(payload["attempt_id"]).length() <= MAX_ID_LENGTH
|
|
and typeof(payload.get("sequence")) == TYPE_INT
|
|
and int(payload["sequence"]) > 0
|
|
and typeof(payload.get("held")) == TYPE_BOOL
|
|
and typeof(payload.get("pressed")) == TYPE_BOOL
|
|
)
|
|
|
|
|
|
static func vector3_to_array(value: Vector3) -> Array[float]:
|
|
return [value.x, value.y, value.z]
|
|
|
|
|
|
static func array_to_vector3(value: Array) -> Vector3:
|
|
if value.size() != 3:
|
|
return Vector3.INF
|
|
return Vector3(float(value[0]), float(value[1]), float(value[2]))
|
|
|
|
|
|
static func _array_is_finite_vector3(value: Array) -> bool:
|
|
for component: Variant in value:
|
|
if (
|
|
typeof(component) not in [TYPE_FLOAT, TYPE_INT]
|
|
or not is_finite(float(component))
|
|
):
|
|
return false
|
|
return true
|