mirror of
https://github.com/lcdr/lu_packets.git
synced 2026-01-06 00:50:29 -06:00
Add support for quickbuild component
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
mod zip_context;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::io::{BufReader, Result as Res};
|
||||
@@ -6,39 +8,21 @@ use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::time::Instant;
|
||||
|
||||
use endio_bit::BEBitReader;
|
||||
use lu_packets::{
|
||||
auth::server::Message as AuthServerMessage,
|
||||
raknet::client::replica::{
|
||||
ComponentConstruction, ComponentSerialization, ReplicaContext,
|
||||
base_combat_ai::{BaseCombatAiConstruction, BaseCombatAiSerialization},
|
||||
bbb::{BbbConstruction, BbbSerialization},
|
||||
buff::BuffConstruction,
|
||||
character::{CharacterConstruction, CharacterSerialization},
|
||||
controllable_physics::{ControllablePhysicsConstruction, ControllablePhysicsSerialization},
|
||||
destroyable::{DestroyableConstruction, DestroyableSerialization},
|
||||
fx::FxConstruction,
|
||||
inventory::{InventoryConstruction, InventorySerialization},
|
||||
level_progression::{LevelProgressionConstruction, LevelProgressionSerialization},
|
||||
phantom_physics::{PhantomPhysicsConstruction, PhantomPhysicsSerialization},
|
||||
player_forced_movement::{PlayerForcedMovementConstruction, PlayerForcedMovementSerialization},
|
||||
possession_control::{PossessionControlConstruction, PossessionControlSerialization},
|
||||
simple_physics::{SimplePhysicsConstruction, SimplePhysicsSerialization},
|
||||
script::ScriptConstruction,
|
||||
skill::SkillConstruction,
|
||||
},
|
||||
world::Lot,
|
||||
world::server::Message as WorldServerMessage,
|
||||
world::client::Message as WorldClientMessage,
|
||||
};
|
||||
use rusqlite::{params, Connection};
|
||||
use zip::{ZipArchive, read::ZipFile};
|
||||
use zip::ZipArchive;
|
||||
use self::zip_context::ZipContext;
|
||||
|
||||
static mut PRINT_PACKETS: bool = false;
|
||||
|
||||
const COMP_ORDER : [u32; 11] = [1, 3, 40, 7, 4, 17, 5, 9, 60, 2, 107];
|
||||
const COMP_ORDER : [u32; 17] = [1, 3, 40, 98, 7, 110, 109, 106, 4, 17, 5, 9, 60, 48, 2, 44, 107];
|
||||
|
||||
struct Cdclient {
|
||||
pub struct Cdclient {
|
||||
conn: Connection,
|
||||
comp_cache: HashMap<Lot, Vec<u32>>,
|
||||
}
|
||||
@@ -50,9 +34,21 @@ impl Cdclient {
|
||||
let rows = stmt.query_map(params![lot], |row| row.get(0)).unwrap();
|
||||
let mut comps = vec![];
|
||||
for row in rows {
|
||||
comps.push(row.unwrap());
|
||||
let value = row.unwrap();
|
||||
comps.push(value);
|
||||
// special case: implied components
|
||||
match value {
|
||||
2 => { comps.push(44); }
|
||||
4 => { comps.push(110); comps.push(109); comps.push(106); }
|
||||
7 => { comps.push(98); }
|
||||
48 => { comps.push(7); }
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
dbg!(&comps);
|
||||
comps.sort();
|
||||
comps.dedup();
|
||||
dbg!(&comps);
|
||||
comps.sort_by_key(|x| COMP_ORDER.iter().position(|y| y == x).unwrap_or(usize::MAX));
|
||||
dbg!(&comps);
|
||||
self.comp_cache.insert(lot, comps);
|
||||
@@ -61,121 +57,6 @@ impl Cdclient {
|
||||
}
|
||||
}
|
||||
|
||||
struct ZipContext<'a> {
|
||||
zip: ZipFile<'a>,
|
||||
lots: &'a mut HashMap<u16, Lot>,
|
||||
cdclient: &'a mut Cdclient,
|
||||
assert_fully_read: bool,
|
||||
}
|
||||
|
||||
impl std::io::Read for ZipContext<'_> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Res<usize> {
|
||||
self.zip.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
// hacky hardcoded components to be able to read player replicas without DB lookup
|
||||
impl ReplicaContext for ZipContext<'_> {
|
||||
fn get_comp_constructions<R: std::io::Read>(&mut self, network_id: u16, lot: Lot) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>> {
|
||||
use endio::Deserialize;
|
||||
|
||||
let comps = self.cdclient.get_comps(lot);
|
||||
|
||||
let mut constrs: Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>> = vec![];
|
||||
for comp in comps {
|
||||
match comp {
|
||||
1 => {
|
||||
constrs.push(|x| Ok(Box::new(ControllablePhysicsConstruction::deserialize(x)?)));
|
||||
}
|
||||
2 => {
|
||||
constrs.push(|x| Ok(Box::new(FxConstruction::deserialize(x)?)));
|
||||
}
|
||||
3 => {
|
||||
constrs.push(|x| Ok(Box::new(SimplePhysicsConstruction::deserialize(x)?)));
|
||||
}
|
||||
4 => {
|
||||
constrs.push(|x| Ok(Box::new(PossessionControlConstruction::deserialize(x)?)));
|
||||
constrs.push(|x| Ok(Box::new(LevelProgressionConstruction::deserialize(x)?)));
|
||||
constrs.push(|x| Ok(Box::new(PlayerForcedMovementConstruction::deserialize(x)?)));
|
||||
constrs.push(|x| Ok(Box::new(CharacterConstruction::deserialize(x)?)));
|
||||
}
|
||||
5 => {
|
||||
constrs.push(|x| Ok(Box::new(ScriptConstruction::deserialize(x)?)));
|
||||
}
|
||||
7 => {
|
||||
constrs.push(|x| Ok(Box::new(BuffConstruction::deserialize(x)?)));
|
||||
constrs.push(|x| Ok(Box::new(DestroyableConstruction::deserialize(x)?)));
|
||||
}
|
||||
9 => {
|
||||
constrs.push(|x| Ok(Box::new(SkillConstruction::deserialize(x)?)));
|
||||
}
|
||||
17 => {
|
||||
constrs.push(|x| Ok(Box::new(InventoryConstruction::deserialize(x)?)));
|
||||
}
|
||||
40 => {
|
||||
constrs.push(|x| Ok(Box::new(PhantomPhysicsConstruction::deserialize(x)?)));
|
||||
}
|
||||
60 => {
|
||||
constrs.push(|x| Ok(Box::new(BaseCombatAiConstruction::deserialize(x)?)));
|
||||
}
|
||||
107 => {
|
||||
constrs.push(|x| Ok(Box::new(BbbConstruction::deserialize(x)?)));
|
||||
}
|
||||
31 | 55 | 56 | 68 => {},
|
||||
x => panic!("{}", x),
|
||||
}
|
||||
}
|
||||
self.lots.insert(network_id, lot);
|
||||
constrs
|
||||
}
|
||||
|
||||
fn get_comp_serializations<R: std::io::Read>(&mut self, network_id: u16) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentSerialization>>> {
|
||||
use endio::Deserialize;
|
||||
|
||||
if let Some(lot) = self.lots.get(&network_id) {
|
||||
let comps = self.cdclient.get_comps(*lot);
|
||||
let mut sers: Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentSerialization>>> = vec![];
|
||||
for comp in comps {
|
||||
match comp {
|
||||
1 => {
|
||||
sers.push(|x| Ok(Box::new(ControllablePhysicsSerialization::deserialize(x)?)));
|
||||
}
|
||||
3 => {
|
||||
sers.push(|x| Ok(Box::new(SimplePhysicsSerialization::deserialize(x)?)));
|
||||
}
|
||||
4 => {
|
||||
sers.push(|x| Ok(Box::new(PossessionControlSerialization::deserialize(x)?)));
|
||||
sers.push(|x| Ok(Box::new(LevelProgressionSerialization::deserialize(x)?)));
|
||||
sers.push(|x| Ok(Box::new(PlayerForcedMovementSerialization::deserialize(x)?)));
|
||||
sers.push(|x| Ok(Box::new(CharacterSerialization::deserialize(x)?)));
|
||||
}
|
||||
7 => {
|
||||
sers.push(|x| Ok(Box::new(DestroyableSerialization::deserialize(x)?)));
|
||||
}
|
||||
17 => {
|
||||
sers.push(|x| Ok(Box::new(InventorySerialization::deserialize(x)?)));
|
||||
}
|
||||
40 => {
|
||||
sers.push(|x| Ok(Box::new(PhantomPhysicsSerialization::deserialize(x)?)));
|
||||
}
|
||||
60 => {
|
||||
sers.push(|x| Ok(Box::new(BaseCombatAiSerialization::deserialize(x)?)));
|
||||
}
|
||||
107 => {
|
||||
sers.push(|x| Ok(Box::new(BbbSerialization::deserialize(x)?)));
|
||||
}
|
||||
2 | 5 | 9 | 31 | 55 | 56 | 68 => {},
|
||||
x => panic!("{}", x),
|
||||
}
|
||||
}
|
||||
self.assert_fully_read = true;
|
||||
return sers;
|
||||
}
|
||||
self.assert_fully_read = false;
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_dirs(dir: &Path, cdclient: &mut Cdclient, level: usize) -> Res<usize> {
|
||||
let mut packet_count = 0;
|
||||
if dir.is_dir() {
|
||||
164
examples/capture_parser/zip_context.rs
Normal file
164
examples/capture_parser/zip_context.rs
Normal file
@@ -0,0 +1,164 @@
|
||||
use std::collections::HashMap;
|
||||
use std::io::Result as Res;
|
||||
|
||||
use endio_bit::BEBitReader;
|
||||
use lu_packets::{
|
||||
raknet::client::replica::{
|
||||
ComponentConstruction, ComponentSerialization, ReplicaContext,
|
||||
base_combat_ai::{BaseCombatAiConstruction, BaseCombatAiSerialization},
|
||||
bbb::{BbbConstruction, BbbSerialization},
|
||||
buff::BuffConstruction,
|
||||
character::{CharacterConstruction, CharacterSerialization},
|
||||
controllable_physics::{ControllablePhysicsConstruction, ControllablePhysicsSerialization},
|
||||
destroyable::{DestroyableConstruction, DestroyableSerialization},
|
||||
fx::FxConstruction,
|
||||
inventory::{InventoryConstruction, InventorySerialization},
|
||||
level_progression::{LevelProgressionConstruction, LevelProgressionSerialization},
|
||||
phantom_physics::{PhantomPhysicsConstruction, PhantomPhysicsSerialization},
|
||||
player_forced_movement::{PlayerForcedMovementConstruction, PlayerForcedMovementSerialization},
|
||||
possession_control::{PossessionControlConstruction, PossessionControlSerialization},
|
||||
quickbuild::{QuickbuildConstruction, QuickbuildSerialization},
|
||||
simple_physics::{SimplePhysicsConstruction, SimplePhysicsSerialization},
|
||||
script::ScriptConstruction,
|
||||
skill::SkillConstruction,
|
||||
},
|
||||
world::Lot,
|
||||
};
|
||||
use zip::read::ZipFile;
|
||||
|
||||
use super::Cdclient;
|
||||
|
||||
pub struct ZipContext<'a> {
|
||||
pub zip: ZipFile<'a>,
|
||||
pub lots: &'a mut HashMap<u16, Lot>,
|
||||
pub cdclient: &'a mut Cdclient,
|
||||
pub assert_fully_read: bool,
|
||||
}
|
||||
|
||||
impl std::io::Read for ZipContext<'_> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Res<usize> {
|
||||
self.zip.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
// hacky hardcoded components to be able to read player replicas without DB lookup
|
||||
impl ReplicaContext for ZipContext<'_> {
|
||||
fn get_comp_constructions<R: std::io::Read>(&mut self, network_id: u16, lot: Lot) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>> {
|
||||
use endio::Deserialize;
|
||||
|
||||
let comps = self.cdclient.get_comps(lot);
|
||||
|
||||
let mut constrs: Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentConstruction>>> = vec![];
|
||||
for comp in comps {
|
||||
match comp {
|
||||
1 => {
|
||||
constrs.push(|x| Ok(Box::new(ControllablePhysicsConstruction::deserialize(x)?)));
|
||||
}
|
||||
3 => {
|
||||
constrs.push(|x| Ok(Box::new(SimplePhysicsConstruction::deserialize(x)?)));
|
||||
}
|
||||
4 => {
|
||||
constrs.push(|x| Ok(Box::new(CharacterConstruction::deserialize(x)?)));
|
||||
}
|
||||
5 => {
|
||||
constrs.push(|x| Ok(Box::new(ScriptConstruction::deserialize(x)?)));
|
||||
}
|
||||
7 => {
|
||||
constrs.push(|x| Ok(Box::new(DestroyableConstruction::deserialize(x)?)));
|
||||
}
|
||||
9 => {
|
||||
constrs.push(|x| Ok(Box::new(SkillConstruction::deserialize(x)?)));
|
||||
}
|
||||
17 => {
|
||||
constrs.push(|x| Ok(Box::new(InventoryConstruction::deserialize(x)?)));
|
||||
}
|
||||
40 => {
|
||||
constrs.push(|x| Ok(Box::new(PhantomPhysicsConstruction::deserialize(x)?)));
|
||||
}
|
||||
44 => {
|
||||
constrs.push(|x| Ok(Box::new(FxConstruction::deserialize(x)?)));
|
||||
}
|
||||
48 => {
|
||||
constrs.push(|x| Ok(Box::new(QuickbuildConstruction::deserialize(x)?)));
|
||||
}
|
||||
60 => {
|
||||
constrs.push(|x| Ok(Box::new(BaseCombatAiConstruction::deserialize(x)?)));
|
||||
}
|
||||
98 => {
|
||||
constrs.push(|x| Ok(Box::new(BuffConstruction::deserialize(x)?)));
|
||||
}
|
||||
106 => {
|
||||
constrs.push(|x| Ok(Box::new(PlayerForcedMovementConstruction::deserialize(x)?)));
|
||||
}
|
||||
107 => {
|
||||
constrs.push(|x| Ok(Box::new(BbbConstruction::deserialize(x)?)));
|
||||
}
|
||||
109 => {
|
||||
constrs.push(|x| Ok(Box::new(LevelProgressionConstruction::deserialize(x)?)));
|
||||
}
|
||||
110 => {
|
||||
constrs.push(|x| Ok(Box::new(PossessionControlConstruction::deserialize(x)?)));
|
||||
}
|
||||
2 | 31 | 55 | 56 | 68 => {},
|
||||
x => panic!("{}", x),
|
||||
}
|
||||
}
|
||||
self.lots.insert(network_id, lot);
|
||||
constrs
|
||||
}
|
||||
|
||||
fn get_comp_serializations<R: std::io::Read>(&mut self, network_id: u16) -> Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentSerialization>>> {
|
||||
use endio::Deserialize;
|
||||
|
||||
if let Some(lot) = self.lots.get(&network_id) {
|
||||
let comps = self.cdclient.get_comps(*lot);
|
||||
let mut sers: Vec<fn(&mut BEBitReader<R>) -> Res<Box<dyn ComponentSerialization>>> = vec![];
|
||||
for comp in comps {
|
||||
match comp {
|
||||
1 => {
|
||||
sers.push(|x| Ok(Box::new(ControllablePhysicsSerialization::deserialize(x)?)));
|
||||
}
|
||||
3 => {
|
||||
sers.push(|x| Ok(Box::new(SimplePhysicsSerialization::deserialize(x)?)));
|
||||
}
|
||||
4 => {
|
||||
sers.push(|x| Ok(Box::new(CharacterSerialization::deserialize(x)?)));
|
||||
}
|
||||
7 => {
|
||||
sers.push(|x| Ok(Box::new(DestroyableSerialization::deserialize(x)?)));
|
||||
}
|
||||
17 => {
|
||||
sers.push(|x| Ok(Box::new(InventorySerialization::deserialize(x)?)));
|
||||
}
|
||||
40 => {
|
||||
sers.push(|x| Ok(Box::new(PhantomPhysicsSerialization::deserialize(x)?)));
|
||||
}
|
||||
48 => {
|
||||
sers.push(|x| Ok(Box::new(QuickbuildSerialization::deserialize(x)?)));
|
||||
}
|
||||
60 => {
|
||||
sers.push(|x| Ok(Box::new(BaseCombatAiSerialization::deserialize(x)?)));
|
||||
}
|
||||
106 => {
|
||||
sers.push(|x| Ok(Box::new(PlayerForcedMovementSerialization::deserialize(x)?)));
|
||||
}
|
||||
107 => {
|
||||
sers.push(|x| Ok(Box::new(BbbSerialization::deserialize(x)?)));
|
||||
}
|
||||
109 => {
|
||||
sers.push(|x| Ok(Box::new(LevelProgressionSerialization::deserialize(x)?)));
|
||||
}
|
||||
110 => {
|
||||
sers.push(|x| Ok(Box::new(PossessionControlSerialization::deserialize(x)?)));
|
||||
}
|
||||
2 | 5 | 9 | 31 | 44 | 55 | 56 | 68 | 98 => {},
|
||||
x => panic!("{}", x),
|
||||
}
|
||||
}
|
||||
self.assert_fully_read = true;
|
||||
return sers;
|
||||
}
|
||||
self.assert_fully_read = false;
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ pub mod level_progression;
|
||||
pub mod phantom_physics;
|
||||
pub mod player_forced_movement;
|
||||
pub mod possession_control;
|
||||
pub mod quickbuild;
|
||||
pub mod script;
|
||||
pub mod simple_physics;
|
||||
pub mod skill;
|
||||
|
||||
72
src/raknet/client/replica/quickbuild.rs
Normal file
72
src/raknet/client/replica/quickbuild.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use std::io::Result as Res;
|
||||
|
||||
use endio::Serialize;
|
||||
use endio_bit::BEBitWriter;
|
||||
use lu_packets_derive::{BitVariantTests, ReplicaSerde};
|
||||
|
||||
use crate::common::{LVec, ObjId};
|
||||
use crate::world::Vector3;
|
||||
use crate::world::gm::client::RebuildChallengeState;
|
||||
use super::{ComponentConstruction, ComponentSerialization};
|
||||
|
||||
#[derive(Debug, PartialEq, ReplicaSerde)]
|
||||
pub struct ActivityUserInfo {
|
||||
pub user_object_id: ObjId,
|
||||
// todo[min_const_generics]
|
||||
// pub activity_values: [f32; 10],
|
||||
pub activity_value_0: f32,
|
||||
pub activity_value_1: f32,
|
||||
pub activity_value_2: f32,
|
||||
pub activity_value_3: f32,
|
||||
pub activity_value_4: f32,
|
||||
pub activity_value_5: f32,
|
||||
pub activity_value_6: f32,
|
||||
pub activity_value_7: f32,
|
||||
pub activity_value_8: f32,
|
||||
pub activity_value_9: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, ReplicaSerde)]
|
||||
pub struct QuickbuildConstructionInfo {
|
||||
pub current_state: RebuildChallengeState,
|
||||
pub show_reset_effect: bool,
|
||||
pub has_activator: bool,
|
||||
pub duration_timer: f32,
|
||||
pub total_incomplete_time: f32,
|
||||
pub unknown: Option<u32>,
|
||||
pub activator_position: Vector3,
|
||||
pub reposition_player: bool,
|
||||
}
|
||||
|
||||
#[derive(BitVariantTests, Debug, PartialEq, ReplicaSerde)]
|
||||
pub struct QuickbuildConstruction {
|
||||
pub activity_user_infos: Option<LVec<u32, ActivityUserInfo>>,
|
||||
pub quickbuild_construction_info: Option<QuickbuildConstructionInfo>,
|
||||
}
|
||||
|
||||
impl ComponentConstruction for QuickbuildConstruction {
|
||||
fn ser(&self, writer: &mut BEBitWriter<Vec<u8>>) -> Res<()> {
|
||||
self.serialize(writer)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, ReplicaSerde)]
|
||||
pub struct QuickbuildSerializationInfo {
|
||||
pub current_state: RebuildChallengeState,
|
||||
pub show_reset_effect: bool,
|
||||
pub has_activator: bool,
|
||||
pub duration_timer: f32,
|
||||
pub total_incomplete_time: f32,
|
||||
}
|
||||
|
||||
#[derive(BitVariantTests, Debug, PartialEq, ReplicaSerde)]
|
||||
pub struct QuickbuildSerialization {
|
||||
pub activity_user_infos: Option<LVec<u32, ActivityUserInfo>>,
|
||||
pub quickbuild_serialization_info: Option<QuickbuildSerializationInfo>,
|
||||
}
|
||||
|
||||
impl ComponentSerialization for QuickbuildSerialization {
|
||||
fn ser(&self, writer: &mut BEBitWriter<Vec<u8>>) -> Res<()> {
|
||||
self.serialize(writer)
|
||||
}
|
||||
}
|
||||
BIN
src/raknet/client/replica/tests/QuickbuildConstruction.bin
Normal file
BIN
src/raknet/client/replica/tests/QuickbuildConstruction.bin
Normal file
Binary file not shown.
31
src/raknet/client/replica/tests/QuickbuildConstruction.rs
Normal file
31
src/raknet/client/replica/tests/QuickbuildConstruction.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
QuickbuildConstruction {
|
||||
activity_user_infos: Some(vec![
|
||||
ActivityUserInfo {
|
||||
user_object_id: 1152921507960010807,
|
||||
activity_value_0: 0.0,
|
||||
activity_value_1: 1.0,
|
||||
activity_value_2: 2.0,
|
||||
activity_value_3: 3.0,
|
||||
activity_value_4: 4.0,
|
||||
activity_value_5: 5.0,
|
||||
activity_value_6: 6.0,
|
||||
activity_value_7: 7.0,
|
||||
activity_value_8: 8.0,
|
||||
activity_value_9: 9.0,
|
||||
}
|
||||
].into()),
|
||||
quickbuild_construction_info: Some(QuickbuildConstructionInfo {
|
||||
current_state: RebuildChallengeState::Open,
|
||||
show_reset_effect: true,
|
||||
has_activator: true,
|
||||
duration_timer: 10.0,
|
||||
total_incomplete_time: 11.0,
|
||||
unknown: Some(12),
|
||||
activator_position: Vector3 {
|
||||
x: 13.0,
|
||||
y: 14.0,
|
||||
z: 15.0,
|
||||
},
|
||||
reposition_player: true,
|
||||
}),
|
||||
}
|
||||
BIN
src/raknet/client/replica/tests/QuickbuildSerialization.bin
Normal file
BIN
src/raknet/client/replica/tests/QuickbuildSerialization.bin
Normal file
Binary file not shown.
24
src/raknet/client/replica/tests/QuickbuildSerialization.rs
Normal file
24
src/raknet/client/replica/tests/QuickbuildSerialization.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
QuickbuildSerialization {
|
||||
activity_user_infos: Some(vec![
|
||||
ActivityUserInfo {
|
||||
user_object_id: 1152921507960010807,
|
||||
activity_value_0: 0.0,
|
||||
activity_value_1: 1.0,
|
||||
activity_value_2: 2.0,
|
||||
activity_value_3: 3.0,
|
||||
activity_value_4: 4.0,
|
||||
activity_value_5: 5.0,
|
||||
activity_value_6: 6.0,
|
||||
activity_value_7: 7.0,
|
||||
activity_value_8: 8.0,
|
||||
activity_value_9: 9.0,
|
||||
}
|
||||
].into()),
|
||||
quickbuild_serialization_info: Some(QuickbuildSerializationInfo {
|
||||
current_state: RebuildChallengeState::Open,
|
||||
show_reset_effect: true,
|
||||
has_activator: true,
|
||||
duration_timer: 10.0,
|
||||
total_incomplete_time: 11.0,
|
||||
}),
|
||||
}
|
||||
Reference in New Issue
Block a user