Added hash value to decide if we should invalidate persited skills and allow a respec.

This commit is contained in:
Sam 2021-11-14 13:32:37 -05:00
parent 6ab2839eaa
commit c8675eaf45
6 changed files with 100 additions and 22 deletions

48
Cargo.lock generated
View File

@ -428,6 +428,15 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array 0.14.4",
]
[[package]]
name = "bstr"
version = "0.2.17"
@ -962,6 +971,15 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "cpufeatures"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
dependencies = [
"libc",
]
[[package]]
name = "cranelift-bforest"
version = "0.74.0"
@ -1381,6 +1399,15 @@ version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2c9736e15e7df1638a7f6eee92a6511615c738246a052af5ba86f039b65aede"
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array 0.14.4",
]
[[package]]
name = "directories-next"
version = "2.0.0"
@ -3804,6 +3831,12 @@ version = "11.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl-probe"
version = "0.1.4"
@ -5122,6 +5155,19 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
[[package]]
name = "sha2"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa"
dependencies = [
"block-buffer",
"cfg-if 1.0.0",
"cpufeatures",
"digest",
"opaque-debug",
]
[[package]]
name = "shaderc"
version = "0.6.3"
@ -6145,6 +6191,7 @@ name = "veloren-common"
version = "0.10.0"
dependencies = [
"approx 0.4.0",
"bincode",
"bitflags",
"chrono",
"chrono-tz",
@ -6170,6 +6217,7 @@ dependencies = [
"roots",
"serde",
"serde_repr",
"sha2",
"slab",
"slotmap 1.0.6",
"specs",

View File

@ -29,6 +29,8 @@ enum-iterator = "0.7"
vek = { version = "=0.14.1", features = ["serde"] }
chrono = "0.4"
chrono-tz = "0.6"
sha2 = "0.9.8"
bincode = "1.3.1"
# Strum
strum = { version = "0.23", features = ["derive"] }

View File

@ -12,7 +12,7 @@ use std::{
time::Duration,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Ord, PartialOrd)]
pub enum ToolKind {
// weapons
Sword,

View File

@ -5,18 +5,20 @@ use crate::{
skills::{GeneralSkill, Skill},
},
};
use hashbrown::{HashMap, HashSet};
use bincode;
use hashbrown::HashMap;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use specs::{Component, DerefFlaggedStorage};
use specs_idvs::IdvStorage;
use std::hash::Hash;
use std::{collections::BTreeSet, hash::Hash};
use tracing::{trace, warn};
pub mod skills;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SkillTreeMap(HashMap<SkillGroupKind, HashSet<Skill>>);
pub struct SkillTreeMap(HashMap<SkillGroupKind, BTreeSet<Skill>>);
impl Asset for SkillTreeMap {
type Loader = assets::RonLoader;
@ -25,7 +27,7 @@ impl Asset for SkillTreeMap {
}
pub struct SkillGroupDef {
pub skills: HashSet<Skill>,
pub skills: BTreeSet<Skill>,
pub total_skill_point_cost: u16,
}
@ -94,9 +96,24 @@ lazy_static! {
"common.skill_trees.skill_prerequisites",
).0
};
pub static ref SKILL_GROUP_HASHES: HashMap<SkillGroupKind, Vec<u8>> = {
let map = SkillTreeMap::load_expect_cloned(
"common.skill_trees.skills_skill-groups_manifest",
).0;
let mut hashes = HashMap::new();
for (skill_group_kind, skills) in map.iter() {
let mut hasher = Sha256::new();
let bincode_input: Vec<_> = skills.iter().map(|skill| (*skill, skill.max_level())).collect();
let hash_input = bincode::serialize(&bincode_input).unwrap_or_default();
hasher.update(hash_input);
let hash_result = hasher.finalize();
hashes.insert(*skill_group_kind, hash_result.iter().copied().collect());
}
hashes
};
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum SkillGroupKind {
General,
Weapon(ToolKind),

View File

@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
/// handled by dedicated ECS systems.
// NOTE: if skill does use some constant, add it to corresponding
// SkillTree Modifiers below.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum Skill {
General(GeneralSkill),
Sword(SwordSkill),
@ -26,7 +26,7 @@ pub enum Skill {
UnlockGroup(SkillGroupKind),
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum SwordSkill {
// Sword passives
InterruptingAttacks,
@ -50,7 +50,7 @@ pub enum SwordSkill {
SSpins,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum AxeSkill {
// Double strike upgrades
DsCombo,
@ -71,7 +71,7 @@ pub enum AxeSkill {
LDistance,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum HammerSkill {
// Single strike upgrades
SsKnockback,
@ -92,7 +92,7 @@ pub enum HammerSkill {
LRange,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum BowSkill {
// Passives
ProjSpeed,
@ -114,7 +114,7 @@ pub enum BowSkill {
SSpread,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum StaffSkill {
// Basic ranged upgrades
BDamage,
@ -133,7 +133,7 @@ pub enum StaffSkill {
SCost,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum SceptreSkill {
// Lifesteal beam upgrades
LDamage,
@ -153,31 +153,31 @@ pub enum SceptreSkill {
ACost,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum GeneralSkill {
HealthIncrease,
EnergyIncrease,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum RollSkill {
Cost,
Strength,
Duration,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum ClimbSkill {
Cost,
Speed,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum SwimSkill {
Speed,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum MiningSkill {
Speed,
OreGain,

View File

@ -547,9 +547,17 @@ fn convert_skill_groups_from_database(
while new_skill_group.earn_skill_point().is_ok() {}
new_skill_groups.push(new_skill_group);
let mut new_skills =
serde_json::from_str::<Vec<skills::Skill>>(&skill_group.skills).unwrap_or_default();
skills.append(&mut new_skills);
// If the hash stored of the skill group is the same as the current hash of the
// skill group, don't invalidate skills
if serde_json::from_str::<Vec<u8>>(&skill_group.hash_val)
.ok()
.as_ref()
== skillset::SKILL_GROUP_HASHES.get(&skill_group_kind)
{
let mut new_skills =
serde_json::from_str::<Vec<skills::Skill>>(&skill_group.skills).unwrap_or_default();
skills.append(&mut new_skills);
}
}
(new_skill_groups, skills)
}
@ -566,7 +574,10 @@ pub fn convert_skill_groups_to_database(
earned_exp: sg.earned_exp as i32,
// If fails to convert, just forces a respec on next login
skills: serde_json::to_string(&sg.ordered_skills).unwrap_or_else(|_| "".to_string()),
hash_val: "".to_string(),
hash_val: serde_json::to_string(
&skillset::SKILL_GROUP_HASHES.get(&sg.skill_group_kind),
)
.unwrap_or_else(|_| "".to_string()),
})
.collect()
}