diff --git a/firebase-rules.json b/firebase-rules.json deleted file mode 100644 index 9836a25f..00000000 --- a/firebase-rules.json +++ /dev/null @@ -1,1873 +0,0 @@ -{ - "rules": { - "campaigns": { - "$uid": { - ".write": "$uid === auth.uid || root.child('users').child(auth.uid).child('admin').exists()", - ".indexOn": "private", - "$campaignId": { - ".validate": "newData.hasChildren(['name'])", - "timestamp": { - ".validate": "newData.isNumber()" - }, - "harmless_key": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "name": { - ".validate": "newData.isString() && newData.val().length <= 200" - }, - "advancement": { - ".validate": true - }, - "private": { - ".validate": "newData.isBoolean()" - }, - "background": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "hk_background": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "inventory": { - "currency": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 4294967295" - }, - "items": { ".validate": true } - }, - "temporary_background": { - "image": { ".validate": "newData.isString() && newData.val().length <= 2000" }, - "youtube": { ".validate": "newData.isString() && newData.val().length <= 2000" }, - "video": { ".validate": "newData.isString() && newData.val().length <= 2000" } - }, - "sharing": { - "image": { ".validate": "newData.isString() && newData.val().length <= 2000" }, - "youtube": { ".validate": "newData.isString() && newData.val().length <= 2000" }, - "message": { ".validate": "newData.isString() && newData.val().length <= 9999" } - }, - "weather": { - "$idx": { - ".validate": "$idx.matches(/^(ash|fog|hail|lightning|quake|rain|sand|smoke|snow)$/)" - } - }, - "companions": { - "$companionId": { - "curHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "tempHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "ac_bonus": { - ".validate": "newData.isNumber() && newData.val() >= -999 && newData.val() <= 999" - }, - "maxHpMod": { - ".validate": "newData.isNumber() && newData.val() >= -9999 && newData.val() <= 9999" - }, - "saves": { - "$idx": { - ".validate": "newData.isString() && newData.val().matches(/^(succes|fail)$/)" - } - }, - "dead": { ".validate": "newData.isBoolean()" }, - "stable": { ".validate": "newData.isBoolean()" }, - "meters": { - "damage": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "damageTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overkill": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overkillTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "healing": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "healingTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overhealing": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overhealingTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - } - }, - "transformed": { - "curHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "maxHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "ac": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - } - }, - "$other": { ".validate": false } - } - }, - "players": { - "$playerId": { - "curHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "tempHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "ac_bonus": { - ".validate": "newData.isNumber() && newData.val() >= -999 && newData.val() <= 999" - }, - "maxHpMod": { - ".validate": "newData.isNumber() && newData.val() >= -9999 && newData.val() <= 9999" - }, - "saves": { - "$idx": { - ".validate": "newData.isString() && newData.val().matches(/^(succes|fail)$/)" - } - }, - "dead": { ".validate": "newData.isBoolean()" }, - "stable": { ".validate": "newData.isBoolean()" }, - "meters": { - "damage": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "damageTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overkill": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overkillTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "healing": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "healingTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overhealing": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overhealingTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - } - }, - "transformed": { - "curHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "maxHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "ac": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - } - }, - "$other": { ".validate": false } - } - }, - "player_count": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "shares": { ".validate": true }, - "$other": { ".validate": false } - } - }, - ".read": true - }, - "search_campaigns": { - ".read": true, - "$uid": { - ".write": "$uid === auth.uid", - "results": { - ".indexOn": ["name"] - } - } - }, - "campaign_notes": { - "$uid": { - "$campaignId": { - "$noteId": { - "title": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "description": { - ".validate": "newData.isString() && newData.val().length <= 1000" - }, - "created": { - ".validate": "newData.isNumber()" - } - }, - ".indexOn": ["created"] - }, - ".read": "$uid === auth.uid", - ".write": "$uid === auth.uid" - } - }, - "users": { - "$uid": { - "username": { - ".write": "$uid === auth.uid || root.child('users').child(auth.uid).child('admin').exists()" - }, - "email": { - ".write": "$uid === auth.uid || root.child('users').child(auth.uid).child('admin').exists()" - }, - "active_campaign": { - ".write": "$uid === auth.uid || root.child('users').child(auth.uid).child('admin').exists()" - }, - "admin": { - ".write": false - }, - "contribute": { - ".write": "root.child('users').child(auth.uid).child('admin').exists()" - }, - "follow": { - ".write": "$uid === auth.uid" - }, - "voucher": { - ".write": "$uid === auth.uid || root.child('users').child(auth.uid).child('admin').exists()" - }, - "patreon_email": { - ".write": "root.child('users').child(auth.uid).child('admin').exists()" - } - }, - ".read": true, - ".indexOn": ["username", "email", "admin", "contribute"] - }, - "search_users": { - ".read": true, - "$uid": { - ".write": "$uid === auth.uid" - }, - ".indexOn": ["username", "email"] - }, - "status": { - ".write": true, - ".read": true, - ".indexOn": "state" - }, - "posters": { - ".write": true, - ".read": true - }, - "patrons": { - ".write": true, - ".read": true, - ".indexOn": "email" - }, - "new_patrons": { - ".write": true, - ".read": true, - ".indexOn": "email" - }, - "patreon_data": { - ".write": true, - ".read": true, - ".indexOn": "timestamp" - }, - "tiers": { - ".write": true, - ".read": true - }, - "settings": { - "$uid": { - ".write": "$uid === auth.uid", - ".read": true - } - }, - "players": { - "$uid": { - "$playerid": { - ".write": "$uid === auth.uid || root.child('character_control').child(auth.uid).child($playerid).child('user').val() === $uid", - ".validate": "newData.hasChildren(['player_name', 'character_name', 'maxHp', 'ac'])", - "sync_character": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "created": { - ".validate": "newData.isNumber()" - }, - "updated": { - ".validate": "newData.isNumber()" - }, - "control": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "campaign_id": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "player_name": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "character_name": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "avatar": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "storage_avatar": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "experience": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 355000" - }, - "level": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "maxHp": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 999" - }, - "ac": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "spell_save_dc": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "speed": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "initiative": { - ".validate": "newData.isNumber() && newData.val() >= -10 && newData.val() <= 99" - }, - "strength": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dexterity": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "constitution": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "intelligence": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "wisdom": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "charisma": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "strength-save-profficient": { - ".validate": "newData.isBoolean()" - }, - "dexterity-save-profficient": { - ".validate": "newData.isBoolean()" - }, - "constitution-save-profficient": { - ".validate": "newData.isBoolean()" - }, - "intelligence-save-profficient": { - ".validate": "newData.isBoolean()" - }, - "wisdom-save-profficient": { - ".validate": "newData.isBoolean()" - }, - "charisma-save-profficient": { - ".validate": "newData.isBoolean()" - }, - "passive_insight": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "passive_investigation": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "passive_perception": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "damage_vulnerabilities": { - "$vulnerabilityIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - } - }, - "damage_resistances": { - "$resistanceIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - } - }, - "damage_immunities": { - "$immunityIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - } - }, - "condition_immunities": { - "$conditionImmunityIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(blinded|charmed|deafened|exhaustion|frightened|grappled|incapacitated|invisible|paralyzed|petrified|poisoned|prone|restrained|stunned|unconscious)$/)" - } - }, - "skills": { - "$skillIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acrobatics|animal Handling|arcana|athletics|deception|history|insight|intimidation|investigation|medicine|nature|perception|performance|persuasion|religion|sleight of Hand|stealth|survival)$/)" - } - }, - "skills_expertise": { - "$skillIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acrobatics|animal Handling|arcana|athletics|deception|history|insight|intimidation|investigation|medicine|nature|perception|performance|persuasion|religion|sleight of Hand|stealth|survival)$/)" - } - }, - "skills_jack_of_all_trades": { - ".validate": "newData.isBoolean()" - }, - "companions": { - "$npcId": { - ".validate": "newData.isBoolean()" - } - }, - "$other": { ".validate": false } - }, - ".read": true - }, - ".read": "root.child('users').child(auth.uid).child('admin').exists()" - }, - "search_players": { - ".read": true, - "$uid": { - ".write": "$uid === auth.uid", - "results": { - "$playerid": { - ".write": "$uid === auth.uid || root.child('character_control').child(auth.uid).child($playerid).child('user').val() === $uid" - }, - ".indexOn": ["character_name"] - } - } - }, - "characters": { - "$uid": { - "$characterId": { - ".write": "$uid === auth.uid || root.child('character_control').child(auth.uid).child($characterId).child('user').val() === $uid" - }, - ".read": true - } - }, - "search_characters": { - ".read": true, - "$uid": { - ".write": "$uid === auth.uid", - "results": { - ".indexOn": ["character_name"] - } - } - }, - "character_control": { - "$uid": { - "$playerid": { - ".write": "data.exists() || newData.child('user').val() === auth.uid || data.child('user').val() === auth.uid" - }, - ".read": true - } - }, - "npcs": { - "$uid": { - "$npcId": { - ".write": "$uid === auth.uid || root.child('character_control').child(auth.uid).child( data.child('player_id').val() ).child('user').val() === $uid", - ".validate": "newData.hasChildren(['name', 'size', 'type', 'challenge_rating', 'armor_class', 'hit_points', 'strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma'])", - "created": { - ".validate": "newData.isNumber()" - }, - "updated": { - ".validate": "newData.isNumber()" - }, - "harmless_key": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "name": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "source": { - ".validate": "newData.isString() && newData.val().length <= 20" - }, - "avatar": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "storage_avatar": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "size": { - ".validate": "newData.isString() && newData.val().matches(/^(Tiny|Small|Medium|Large|Huge|Gargantuan)$/)" - }, - "type": { - ".validate": "newData.isString() && newData.val().matches(/^(Aberration|Beast|Celestial|Construct|Dragon|Elemental|Fey|Fiend|Giant|Humanoid|Monstrosity|Ooze|Plant|Swarm of tiny beasts|Undead)$/)" - }, - "subtype": { - ".validate": "newData.isString() && newData.val().length <= 25" - }, - "alignment": { - ".validate": "newData.isString() && newData.val().matches(/^(Any|Any alignment|Unaligned|Lawful Good|Neutral Good|Chaotic Good|Lawful neutral|Neutral|Chaotic neutral|Lawful evil|Neutral evil|Chaotic evil)$/i)" - }, - "walk_speed": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "swim_speed": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "fly_speed": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "burrow_speed": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "climb_speed": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "languages": { - "$langugeIndex": { - ".validate": "newData.isString() && newData.val().length <= 100" - } - }, - "challenge_rating": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 30" - }, - "proficiency": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 10" - }, - "friendly": { - ".validate": "newData.isBoolean()" - }, - "player_id": { - ".validate": "newData.isString() && newData.val().length <= 50" - }, - "armor_class": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "hit_points": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 9999" - }, - "hit_dice": { - ".validate": "newData.isString() && newData.val().length <= 10 && (newData.val().length === 0 ||newData.val().matches(/^[0-9]+d[0-9]+$/))" - }, - - "senses": { - "blindsight": { - "blindsight": { - ".validate": "newData.isBoolean()" - }, - "range": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "comments": { - ".validate": "newData.isString() && newData.val().length <= 999" - }, - "$other": { ".validate": false } - }, - "darkvision": { - "darkvision": { - ".validate": "newData.isBoolean()" - }, - "range": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "comments": { - ".validate": "newData.isString() && newData.val().length <= 999" - }, - "$other": { ".validate": false } - }, - "tremorsense": { - "tremorsense": { - ".validate": "newData.isBoolean()" - }, - "range": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "comments": { - ".validate": "newData.isString() && newData.val().length <= 999" - }, - "$other": { ".validate": false } - }, - "truesight": { - "truesight": { - ".validate": "newData.isBoolean()" - }, - "range": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "comments": { - ".validate": "newData.isString() && newData.val().length <= 999" - }, - "$other": { ".validate": false } - } - }, - - "strength": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 99" - }, - "dexterity": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 99" - }, - "constitution": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 99" - }, - "intelligence": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 99" - }, - "wisdom": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 99" - }, - "charisma": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 99" - }, - - "saving_throws": { - "$savingIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(strength|dexterity|constitution|intelligence|wisdom|charisma)$/)" - } - }, - - "skills": { - "$skillIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acrobatics|animal Handling|arcana|athletics|deception|history|insight|intimidation|investigation|medicine|nature|perception|performance|persuasion|religion|sleight of Hand|stealth|survival)$/)" - } - }, - "skills_expertise": { - "$skillIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acrobatics|animal Handling|arcana|athletics|deception|history|insight|intimidation|investigation|medicine|nature|perception|performance|persuasion|religion|sleight of Hand|stealth|survival)$/)" - } - }, - "skill_modifiers": { - "acrobatics": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "animal Handling": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "arcana": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "athletics": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "deception": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "history": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "insight": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "intimidation": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "investigation": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "medicine": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "nature": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "perception": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "performance": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "persuasion": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "religion": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "sleight of Hand": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "stealth": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "survival": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "$other": { - ".validate": false - } - }, - - "damage_vulnerabilities": { - "$vulnerabilityIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - } - }, - "damage_resistances": { - "$resistanceIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - } - }, - "damage_immunities": { - "$immunityIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - } - }, - "condition_immunities": { - "$conditionImmunityIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(blinded|charmed|deafened|exhaustion|frightened|grappled|incapacitated|invisible|paralyzed|petrified|poisoned|prone|restrained|stunned|unconscious)$/)" - } - }, - - "caster_ability": { - ".validate": "newData.isString() && newData.val().matches(/^(strength|dexterity|constitution|intelligence|wisdom|charisma)$/)" - }, - "caster_level": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "caster_save_dc": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "caster_spell_attack": { - ".validate": "newData.isNumber() && newData.val() >= -10 && newData.val() <= 99" - }, - "caster_spell_slots": { - "$slotIndex": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 9" - } - }, - "caster_spells": { - "$spellId": { - "level": { - ".validate": "newData.isNumber() && newData.val() >= -1 && newData.val() <= 9" - }, - "name": { - ".validate": "newData.isString() && newData.val().length <= 50" - }, - "custom": { - ".validate": "newData.isBoolean()" - }, - "$other": { ".validate": false } - } - }, - - "innate_ability": { - ".validate": "newData.isString() && newData.val().matches(/^(strength|dexterity|constitution|intelligence|wisdom|charisma)$/)" - }, - "innate_save_dc": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "innate_spell_attack": { - ".validate": "newData.isNumber() && newData.val() >= -10 && newData.val() <= 99" - }, - "innate_spells": { - "$spellId": { - "limit": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 10" - }, - "name": { - ".validate": "newData.isString() && newData.val().length <= 50" - }, - "custom": { - ".validate": "newData.isBoolean()" - }, - - "$other": { ".validate": false } - } - }, - - "special_abilities": { - "$abilityIndex": { - ".validate": "newData.hasChildren(['name'])", - "name": { - ".validate": "newData.isString() && newData.val().length <= 50" - }, - "recharge": { - ".validate": "newData.isString() && (newData.val().length === 0 || newData.val().matches(/^[0-9]+(-[0-9]+)*$/) || newData.val().matches(/^(rest)$/))" - }, - "limit": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 9" - }, - "limit_type": { - ".validate": "newData.isString() && newData.val().matches(/^(day|turn)$/)" - }, - "desc": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "reach": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "range": { - ".validate": "newData.isString() && (newData.val().length === 0 || newData.val().matches(/^[0-9]+(\\/[0-9]+)*$/))" - }, - "aoe_type": { - ".validate": "newData.isString() && newData.val().matches(/^(cone|cube|cylinder|line|sphere|square|square feet)$/)" - }, - "aoe_size": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "versatile": { - ".validate": "newData.isBoolean()" - }, - "versatile_one": { - ".validate": "newData.isString() && newData.val().length <= 25" - }, - "versatile_two": { - ".validate": "newData.isString() && newData.val().length <= 25" - }, - "options": { - "$optionIndex": { - ".validate": "newData.isString() && newData.val().length <= 30" - } - }, - "action_list": { - "$listIndex": { - "type": { - ".validate": "newData.isString() && newData.val().matches(/^(melee_weapon|ranged_weapon|spell_attack|save|damage|healing|other)$/)" - }, - "attack_bonus": { - ".validate": "newData.isNumber() && newData.val() >= -10 && newData.val() <= 99" - }, - "save_ability": { - ".validate": "newData.isString() && newData.val().matches(/^(strength|dexterity|constitution|intelligence|wisdom|charisma)$/)" - }, - "save_dc": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "rolls": { - "$rollIndex": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "versatile_damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "versatile_magical": { - ".validate": "newData.isBoolean()" - }, - "versatile_dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "versatile_dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "versatile_fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "options": { - "$optionKey": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "ignore": { - ".validate": "newData.isBoolean()" - } - } - }, - "projectile_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "miss_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "save_fail_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "special": { - "$specialIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(siphon_full|siphon_half|drain)$/)" - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - - "actions": { - "$actionIndex": { - ".validate": "newData.hasChildren(['name'])", - "name": { - ".validate": "newData.isString() && newData.val().length <= 50" - }, - "recharge": { - ".validate": "newData.isString() && (newData.val().length === 0 || newData.val().matches(/^[0-9]+(-[0-9]+)*$/) || newData.val().matches(/^(rest)$/))" - }, - "limit": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 9" - }, - "limit_type": { - ".validate": "newData.isString() && newData.val().matches(/^(day|turn)$/)" - }, - "desc": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "reach": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "range": { - ".validate": "newData.isString() && (newData.val().length === 0 || newData.val().matches(/^[0-9]+(\\/[0-9]+)*$/))" - }, - "aoe_type": { - ".validate": "newData.isString() && newData.val().matches(/^(cone|cube|cylinder|line|sphere|square|square feet)$/)" - }, - "aoe_size": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "versatile": { - ".validate": "newData.isBoolean()" - }, - "versatile_one": { - ".validate": "newData.isString() && newData.val().length <= 25" - }, - "versatile_two": { - ".validate": "newData.isString() && newData.val().length <= 25" - }, - "options": { - "$optionIndex": { - ".validate": "newData.isString() && newData.val().length <= 30" - } - }, - "action_list": { - "$listIndex": { - "type": { - ".validate": "newData.isString() && newData.val().matches(/^(melee_weapon|ranged_weapon|spell_attack|save|damage|healing|other)$/)" - }, - "attack_bonus": { - ".validate": "newData.isNumber() && newData.val() >= -10 && newData.val() <= 99" - }, - "save_ability": { - ".validate": "newData.isString() && newData.val().matches(/^(strength|dexterity|constitution|intelligence|wisdom|charisma)$/)" - }, - "save_dc": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "rolls": { - "$rollIndex": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "versatile_damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "versatile_magical": { - ".validate": "newData.isBoolean()" - }, - "versatile_dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "versatile_dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "versatile_fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "options": { - "$optionKey": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "ignore": { - ".validate": "newData.isBoolean()" - } - } - }, - "projectile_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "miss_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "save_fail_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "special": { - "$specialIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(siphon_full|siphon_half|drain)$/)" - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - - "legendary_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 9" - }, - "legendary_actions": { - "$legendaryIndex": { - ".validate": "newData.hasChildren(['name', 'legendary_cost'])", - "legendary_cost": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9" - }, - "name": { - ".validate": "newData.isString() && newData.val().length <= 50" - }, - "recharge": { - ".validate": "newData.isString() && (newData.val().length === 0 || newData.val().matches(/^[0-9]+(-[0-9]+)*$/) || newData.val().matches(/^(rest)$/))" - }, - "limit": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 9" - }, - "limit_type": { - ".validate": "newData.isString() && newData.val().matches(/^(day|turn)$/)" - }, - "desc": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "reach": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "range": { - ".validate": "newData.isString() && (newData.val().length === 0 || newData.val().matches(/^[0-9]+(\\/[0-9]+)*$/))" - }, - "aoe_type": { - ".validate": "newData.isString() && newData.val().matches(/^(cone|cube|cylinder|line|sphere|square|square feet)$/)" - }, - "aoe_size": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "versatile": { - ".validate": "newData.isBoolean()" - }, - "versatile_one": { - ".validate": "newData.isString() && newData.val().length <= 25" - }, - "versatile_two": { - ".validate": "newData.isString() && newData.val().length <= 25" - }, - "options": { - "$optionIndex": { - ".validate": "newData.isString() && newData.val().length <= 30" - } - }, - "action_list": { - "$listIndex": { - "type": { - ".validate": "newData.isString() && newData.val().matches(/^(melee_weapon|ranged_weapon|spell_attack|save|damage|healing|other)$/)" - }, - "attack_bonus": { - ".validate": "newData.isNumber() && newData.val() >= -10 && newData.val() <= 99" - }, - "save_ability": { - ".validate": "newData.isString() && newData.val().matches(/^(strength|dexterity|constitution|intelligence|wisdom|charisma)$/)" - }, - "save_dc": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "rolls": { - "$rollIndex": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "versatile_damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "versatile_magical": { - ".validate": "newData.isBoolean()" - }, - "versatile_dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "versatile_dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "versatile_fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "options": { - "$optionKey": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "ignore": { - ".validate": "newData.isBoolean()" - } - } - }, - "projectile_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "miss_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "save_fail_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "special": { - "$specialIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(siphon_full|siphon_half|drain)$/)" - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - - "reactions": { - "$reactionIndex": { - ".validate": "newData.hasChildren(['name'])", - "name": { - ".validate": "newData.isString() && newData.val().length <= 50" - }, - "recharge": { - ".validate": "newData.isString() && (newData.val().length === 0 || newData.val().matches(/^[0-9]+(-[0-9]+)*$/) || newData.val().matches(/^(rest)$/))" - }, - "limit": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 9" - }, - "limit_type": { - ".validate": "newData.isString() && newData.val().matches(/^(day|turn)$/)" - }, - "desc": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "reach": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "range": { - ".validate": "newData.isString() && (newData.val().length === 0 || newData.val().matches(/^[0-9]+(\\/[0-9]+)*$/))" - }, - "aoe_type": { - ".validate": "newData.isString() && newData.val().matches(/^(cone|cube|cylinder|line|sphere|square|square feet)$/)" - }, - "aoe_size": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "versatile": { - ".validate": "newData.isBoolean()" - }, - "versatile_one": { - ".validate": "newData.isString() && newData.val().length <= 25" - }, - "versatile_two": { - ".validate": "newData.isString() && newData.val().length <= 25" - }, - "options": { - "$optionIndex": { - ".validate": "newData.isString() && newData.val().length <= 30" - } - }, - "action_list": { - "$listIndex": { - "type": { - ".validate": "newData.isString() && newData.val().matches(/^(melee_weapon|ranged_weapon|spell_attack|save|damage|healing|other)$/)" - }, - "attack_bonus": { - ".validate": "newData.isNumber() && newData.val() >= -10 && newData.val() <= 99" - }, - "save_ability": { - ".validate": "newData.isString() && newData.val().matches(/^(strength|dexterity|constitution|intelligence|wisdom|charisma)$/)" - }, - "save_dc": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "rolls": { - "$rollIndex": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "versatile_damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "versatile_magical": { - ".validate": "newData.isBoolean()" - }, - "versatile_dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "versatile_dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "versatile_fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "options": { - "$optionKey": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "ignore": { - ".validate": "newData.isBoolean()" - } - } - }, - "projectile_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "miss_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "save_fail_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "special": { - "$specialIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(siphon_full|siphon_half|drain)$/)" - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - }, - ".write": "root.child('users').child(auth.uid).child('admin').exists()", - ".read": true, - ".indexOn": ["name", "harmless_key"] - }, - ".read": "root.child('users').child(auth.uid).child('admin').exists()" - }, - "search_npcs": { - ".read": true, - "$uid": { - ".write": "$uid === auth.uid", - "results": { - ".indexOn": ["name", "challenge_rating", "type"] - } - } - }, - "custom_items": { - "$uid": { - ".write": "$uid === auth.uid", - ".read": true - }, - ".read": "root.child('users').child(auth.uid).child('admin').exists()" - }, - "search_custom_items": { - ".read": true, - "$uid": { - ".write": "$uid === auth.uid", - "results": { - ".indexOn": ["name"] - } - } - }, - "encounters": { - "$uid": { - ".write": "$uid === auth.uid || root.child('users').child(auth.uid).child('admin').exists()", - ".read": true, - - "$campaignId": { - ".indexOn": "entities/id", - "$encounterId": { - "timestamp": { - ".validate": "newData.isNumber()" - }, - "name": { - ".validate": "newData.isString() && newData.val().length <= 200" - }, - "encounter": { - ".validate": "newData.isString() && newData.val().length <= 200" - }, - "turn": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "round": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999" - }, - "finished": { - ".validate": "newData.isBoolean()" - }, - "audio": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "background": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "hk_background": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "currency": { - "$coin": { - ".validate": "$coin.matches(/^(cp|sp|ep|gp|pp)$/)" - } - }, - "loot": { - "$itemId": { - "linked_item": { - "custom": { - ".validate": "newData.isBoolean()" - }, - "key": { - ".validate": "newData.isString() && newData.val().length <= 100" - } - }, - "public_name": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "public_description": { - ".validate": "newData.isString() && newData.val().length <= 9999" - } - } - }, - "xp": { - "calculated": { - ".validate": "newData.isNumber() && newData.val() >= 0" - }, - "overwrite": { - ".validate": "newData.isString() || newData.isNumber()" - } - }, - "weather": { - "$idx": { - ".validate": "$idx.matches(/^(ash|fog|hail|lightning|quake|rain|sand|smoke|snow)$/)" - } - }, - "entities": { - "$entityId": { - "id": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "key": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "entityType": { - ".validate": "newData.isString() && newData.val().matches(/^(player|npc|companion)$/)" - }, - "npc": { - ".validate": "newData.isString() && newData.val().matches(/^(srd|custom|api)$/)" - }, - "name": { - ".validate": "newData.isString() && newData.val().length <= 200" - }, - "active": { - ".validate": "newData.isBoolean()" - }, - "hidden": { - ".validate": "newData.isBoolean()" - }, - "initiative": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "ac": { - ".validate": "(newData.isNumber() && newData.val() >= 1 && newData.val() <= 9999) || (newData.isString() && newData.val().length <= 10)" - }, - "ac_bonus": { - ".validate": "newData.isNumber() && newData.val() >= -999 && newData.val() <= 9999" - }, - "curHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "maxHp": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 9999" - }, - "maxHpMod": { - ".validate": "newData.isNumber() && newData.val() >= -9999 && newData.val() <= 9999" - }, - "tempHp": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999" - }, - "color_label": { - ".validate": "newData.isString() && newData.val().length <= 10" - }, - "conditions": { - "exhaustion": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 6" - }, - "$condition": { - ".validate": "newData.isBoolean() && $condition.matches(/^(blinded|charmed|deafened|exhaustion|frightened|grappled|incapacitated|invisible|paralyzed|petrified|poisoned|prone|restrained|stunned|unconscious)$/)" - } - }, - "reminders": { - "$remindId": { - "action": { - ".validate": "newData.isString() && newData.val().matches(/^(remove|notify)$/)" - }, - "color": { - ".validate": "newData.isString() && newData.val().matches(/^(green-light|yellow-light|orange-light|red-light|purple|blue-light)$/)" - }, - "trigger": { - ".validate": "newData.isString() && newData.val().matches(/^(endTurn|startTurn|damage|timed)$/)" - }, - "rounds": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 99" - }, - "title": { - ".validate": "newData.isString() && newData.val().length <= 999" - }, - "notify": { - ".validate": "newData.isString() && newData.val().length <= 999" - }, - "variables": { - "$varName": { - "$vi": { - ".validate": "newData.isString() && newData.val().length <= 5" - } - } - } - } - }, - "settings": { - "ac": { - ".validate": "newData.isBoolean()" - }, - "health": { - ".validate": "newData.isBoolean() || newData.val().matches(/^(obscured)$/)" - }, - "name": { - ".validate": "newData.isBoolean()" - } - }, - "meters": { - "damage": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "damageTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overkill": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overkillTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "healing": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "healingTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overhealing": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - }, - "overhealingTaken": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 999999" - } - }, - "limited_uses": { - "caster": { - "$lvl": { - ".validate": "newData.isNumber() && newData.val() <= 100" - } - }, - "innate": { - "$spellId": { - ".validate": "newData.isNumber() && newData.val() <= 100" - } - }, - "actions": { - "$actionId": { - ".validate": "newData.isNumber() && newData.val() <= 100" - } - }, - "legendary_actions": { - "legendaries_used": { - ".validate": "newData.isNumber() && newData.val() <= 100" - } - } - } - } - }, - "requests": { - ".write": true - }, - "$other": { ".validate": false } - } - } - }, - ".read": "root.child('users').child(auth.uid).child('admin').exists()" - }, - "search_encounters": { - ".read": true, - "$uid": { - ".write": "$uid === auth.uid", - "results": { - "$campaignId": { - ".indexOn": ["name", "finished"] - } - } - } - }, - "meters": { - "$uid": { - ".write": "$uid === auth.uid", - ".read": true - } - }, - "track": { - "$uid": { - ".write": true - }, - ".read": true - }, - "broadcast": { - "$uid": { - ".write": "$uid === auth.uid" - }, - ".read": true - }, - "conditions": { - ".write": false, - ".read": true - }, - "items": { - ".write": false, - ".read": true - }, - "abilities": { - ".write": false, - ".read": true - }, - "spells": { - "$uid": { - "$spellId": { - ".validate": "newData.hasChildren(['name', 'level', 'school', 'cast_time', 'cast_time_type', 'range_type', 'duration_type', 'aoe_type', 'scaling'])", - "harmless_key": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "created": { - ".validate": "newData.isNumber()" - }, - "updated": { - ".validate": "newData.isNumber()" - }, - "name": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "source": { - ".validate": "newData.isString() && newData.val().length <= 30" - }, - "level": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9" - }, - "school": { - ".validate": "newData.isString() && newData.val().matches(/^(abjuration|conjuration|divination|enchantment|evocation|illusion|necromancy|transmutation)$/i)" - }, - "cast_time": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 999" - }, - "cast_time_type": { - ".validate": "newData.isString() && newData.val().matches(/^(action|bonus_action|reaction|minute|hour|no_action|special)$/i)" - }, - "cast_time_react_desc": { - ".validate": "newData.isString() && newData.val().length <= 200" - }, - "components": { - "$componentIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(verbal|somatic|material)$/i)" - } - }, - "material_description": { - ".validate": "newData.isString() && newData.val().length <= 500" - }, - "range_type": { - ".validate": "newData.isString() && newData.val().matches(/^(self|touch|ranged|sight|unlimited|special)$/i)" - }, - "range": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 9999999" - }, - "classes": { - "$classIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(bard|barbarian|cleric|druid|fighter|monk|paladin|ranger|rogue|sorcerer|warlock|wizard)$/i)" - } - }, - "duration_type": { - ".validate": "newData.isString() && newData.val().matches(/^(concentration|instantaneous|special|time|until_dispelled|until_dispelled_or_triggered)$/i)" - }, - "duration": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 999" - }, - "duration_scale": { - ".validate": "newData.isString() && newData.val().matches(/^(round|minute|hour|day)$/i)" - }, - "aoe_type": { - ".validate": "newData.isString() && newData.val().matches(/^(none|cone|cube|cylinder|line|radius|sphere|square|square feet)$/i)" - }, - "aoe_size": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99999" - }, - "ritual": { - ".validate": "newData.isBoolean()" - }, - "scaling": { - ".validate": "newData.isString() && newData.val().matches(/^(none|character_level|spell_scale|spell_level)$/i)" - }, - "description": { - ".validate": "newData.isString() && newData.val().length <= 5000" - }, - "higher_level": { - ".validate": "newData.isString() && newData.val().length <= 1000" - }, - "projectiles": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "projectile_scaling": { - "$scalingIndex": { - ".validate": "newData.hasChildren(['level'])", - "level": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "projectile_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 25" - }, - "$other": { ".validate": false } - } - }, - "options": { - "$optionIndex": { - ".validate": "newData.isString() && newData.val().length <= 30" - } - }, - "actions": { - "$actionIndex": { - "name": { - ".validate": "newData.isString() && newData.val().length <= 100" - }, - "type": { - ".validate": "newData.isString() && newData.val().matches(/^(melee_weapon|ranged_weapon|spell_attack|save|damage|healing|other)$/)" - }, - "save_ability": { - ".validate": "newData.isString() && newData.val().matches(/^(strength|dexterity|constitution|intelligence|wisdom|charisma)$/)" - }, - "optional": { - ".validate": "newData.isBoolean()" - }, - "rolls": { - "$rollIndex": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "options": { - "$optionKey": { - "damage_type": { - ".validate": "newData.isString() && newData.val().matches(/^(acid|bludgeoning|cold|fire|force|lightning|necrotic|piercing|poison|psychic|radiant|slashing|thunder|non_magical_bludgeoning|non_magical_piercing|non_magical_slashing)$/)" - }, - "magical": { - ".validate": "newData.isBoolean()" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "dice_type": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "ignore": { - ".validate": "newData.isBoolean()" - } - } - }, - "primary": { - ".validate": "newData.isBoolean()" - }, - "miss_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "save_fail_mod": { - ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 2" - }, - "special": { - "$specialIndex": { - ".validate": "newData.isString() && newData.val().matches(/^(siphon_full|siphon_half|drain)$/)" - } - }, - "scaling": { - "$scalingIndex": { - ".validate": "newData.hasChildren(['level'])", - "level": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 20" - }, - "dice_count": { - ".validate": "newData.isNumber() && newData.val() >= 1 && newData.val() <= 99" - }, - "fixed_val": { - ".validate": "newData.isNumber() && newData.val() >= -99 && newData.val() <= 99" - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false } - } - }, - "$other": { ".validate": false }, - ".write": "$uid === auth.uid" - }, - ".write": "root.child('users').child(auth.uid).child('admin').exists()", - ".read": true, - ".indexOn": ["metadata/tagged", "metadata/finished"] - } - }, - "search_spells": { - ".read": true, - "$uid": { - ".write": "$uid === auth.uid", - "results": { - ".indexOn": ["name"] - } - } - }, - "reminders": { - "$uid": { - ".write": "$uid === auth.uid", - ".read": true - }, - ".read": "root.child('users').child(auth.uid).child('admin').exists()" - }, - "search_reminders": { - ".read": true, - "$uid": { - ".write": "$uid === auth.uid", - "results": { - ".indexOn": ["name"] - } - } - }, - "vouchers": { - "$voucherId": { - "times_used": { - ".write": true - } - }, - ".read": true, - ".write": "root.child('users').child(auth.uid).child('admin').exists()" - }, - "voucher_history": { - "$uid": { - ".read": "$uid === auth.uid", - ".write": "$uid === auth.uid" - } - }, - "soundboard": { - "$uid": { - "$soundboardId": { - ".validate": "newData.hasChildren(['type', 'name', 'url'])", - "type": { - ".validate": "newData.isString() && newData.val().matches(/^(music|ambience)$/)" - }, - "name": { - ".validate": "newData.isString() && newData.val().length <= 20" - }, - "url": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "image": { - ".validate": "newData.isString() && newData.val().length <= 2000" - }, - "$other": { ".validate": false } - }, - ".indexOn": ["type"], - ".read": "$uid === auth.uid", - ".write": "$uid === auth.uid" - } - } - } -} diff --git a/src/components/campaign/Players.vue b/src/components/campaign/Players.vue index ce5b97e0..aa3c4d2b 100644 --- a/src/components/campaign/Players.vue +++ b/src/components/campaign/Players.vue @@ -77,7 +77,7 @@ Edit Group Health +
+ + +
@@ -62,11 +63,6 @@ export default { players: {}, allSelected: true, indeterminate: false, - options: [ - { label: "Divide over", value: "divide" }, - { label: "Award to all", value: "toAll" }, - ], - awardType: "divide", }; }, computed: { @@ -117,18 +113,10 @@ export default { ...mapActions("campaigns", ["get_campaign", "set_share"]), ...mapActions("players", ["get_player", "set_player_prop"]), ...mapActions("encounters", ["set_xp", "update_encounter_prop"]), - awardPlayer() { - let amount = this.amount; - - if (this.awardType === "divide") { - amount = Math.floor(this.amount / this.awardTo.length); - } - return parseInt(amount); - }, - awardXP() { + awardXP(awardType) { let amount = parseInt(this.amount); - if (this.awardType === "divide") { + if (awardType === "divide") { amount = Math.floor(this.amount / this.awardTo.length); }