Implement string conversion for byte arrays

This commit is contained in:
lcdr
2021-01-01 13:48:45 +01:00
parent cad90380d4
commit 9799241b55
18 changed files with 48 additions and 23 deletions

View File

@@ -69,15 +69,27 @@ macro_rules! lu_str {
type Error = AsciiError;
fn try_from(string: &[u8]) -> Result<Self, Self::Error> {
if string.len() >= $n {
// actually length error but whatever
return Err(AsciiError);
}
let mut bytes = [0u8; $n];
// todo: ascii range check
for (i, chr) in string.iter().take($n-1).enumerate() {
for (i, chr) in string.iter().enumerate() {
bytes[i] = *chr;
}
let bytes = unsafe { std::mem::transmute(bytes) };
Ok(Self(bytes))
}
}
impl<const N: usize> TryFrom<&[u8; N]> for $name {
type Error = AsciiError;
fn try_from(string: &[u8; N]) -> Result<Self, Self::Error> {
Self::try_from(&string[..])
}
}
}
}

View File

@@ -40,6 +40,14 @@ impl<L> TryFrom<&[u8]> for LuVarString<L> {
}
}
impl<L, const N: usize> TryFrom<&[u8; N]> for LuVarString<L> {
type Error = AsciiError;
fn try_from(string: &[u8; N]) -> Result<Self, Self::Error> {
Self::try_from(&string[..])
}
}
impl<L> From<&LuWStr> for LuVarWString<L> {
fn from(string: &LuWStr) -> Self {
Self(string.into(), PhantomData)

View File

@@ -2,6 +2,7 @@
Documentation and (de-)serialization support for LU's network protocol.
*/
#![feature(arbitrary_enum_discriminant)]
#![feature(min_const_generics)]
#![feature(specialization)]
#![allow(incomplete_features)]
@@ -97,7 +98,7 @@ macro_rules! amf3 {
"bool": true,
"i64": i64::MAX,
"u64": u64::MAX,
"string": b"byte slice"[..],
"string": b"byte slice",
};
# }
```

View File

@@ -1,7 +1,7 @@
FxConstruction {
active_effects: vec![
EffectInfo {
effect_name: lu!(&b"effect_name"[..]),
effect_name: lu!(b"effect_name"),
effect_id: 1,
effect_type: lu!("effect_type"),
priority: 2.0,

View File

@@ -19,7 +19,7 @@ ClientMessage::CreateCharacter(
"reputation": 0i64,
"template": 1i32,
"objid": 1152921510115197038u64,
"xmlData": &b"<obj v=\"1\"><mf hc=\"1\" hs=\"9\" hd=\"0\" t=\"15\" l=\"15\" hdc=\"0\" cd=\"21\" lh=\"38710288\" rh=\"38262980\" es=\"3\" ess=\"22\" ms=\"24\"/><char acct=\"1267289\" cc=\"0\" gm=\"0\" ft=\"1\"/><dest hm=\"4\" hc=\"4\" im=\"0\" ic=\"0\" am=\"0\" ac=\"0\" d=\"0\"/><inv><items><in t=\"0\"><i l=\"4511\" id=\"1152921510115197039\" s=\"0\" eq=\"1\"/><i l=\"2516\" id=\"1152921510115197040\" s=\"1\" eq=\"1\"/></in></items></inv><lvl l=\"1\" cv=\"1\" sb=\"500\"/></obj>"[..],
"xmlData": b"<obj v=\"1\"><mf hc=\"1\" hs=\"9\" hd=\"0\" t=\"15\" l=\"15\" hdc=\"0\" cd=\"21\" lh=\"38710288\" rh=\"38262980\" es=\"3\" ess=\"22\" ms=\"24\"/><char acct=\"1267289\" cc=\"0\" gm=\"0\" ft=\"1\"/><dest hm=\"4\" hc=\"4\" im=\"0\" ic=\"0\" am=\"0\" ac=\"0\" d=\"0\"/><inv><items><in t=\"0\"><i l=\"4511\" id=\"1152921510115197039\" s=\"0\" eq=\"1\"/><i l=\"2516\" id=\"1152921510115197040\" s=\"1\" eq=\"1\"/></in></items></inv><lvl l=\"1\" cv=\"1\" sb=\"500\"/></obj>",
"editor_enabled": false,
"position.y": 613.32623f32,
"chatmode": 0i32,

View File

@@ -1,6 +1,6 @@
ClientMessage::TransferToWorld(
TransferToWorld {
redirect_ip: lu!(&b"171.20.35.42"[..]),
redirect_ip: lu!(b"171.20.35.42"),
redirect_port: 2005,
is_maintenance_transfer: false,
},

View File

@@ -1,5 +1,5 @@
GameMessage::LockNodeRotation(
LockNodeRotation {
node_name: lu!(&b"base"[..]),
node_name: lu!(b"base"),
},
)

View File

@@ -4,6 +4,6 @@ GameMessage::NotifyClientObject(
param1: 5,
param2: 0,
param_obj: 1152921507004579166,
param_str: lu!(&b""[..]),
param_str: lu!(b""),
},
)

View File

@@ -4,6 +4,6 @@ GameMessage::NotifyClientZoneObject(
param1: 395,
param2: 0,
param_obj: 1152921507004579166,
param_str: lu!(&b"true"[..]),
param_str: lu!(b"true"),
},
)

View File

@@ -3,7 +3,7 @@ GameMessage::PlayFxEffect(
effect_id: -1,
effect_type: lu!("equip-head"),
scale: 1.0,
name: lu!(&b""[..]),
name: lu!(b""),
priority: 1.07,
secondary: 0,
serialize: true,

View File

@@ -1,9 +1,9 @@
GameMessage::ScriptNetworkVarUpdate(
ScriptNetworkVarUpdate {
table_of_vars: lnv! {
"Define_Player_To_UI": b"1152921510757277251"[..],
"Define_Player_To_UI": b"1152921510757277251",
"Show_ScoreBoard": true,
"Update_ScoreBoard_Players.1": b"1152921510757277251"[..],
"Update_ScoreBoard_Players.1": b"1152921510757277251",
},
},
)

View File

@@ -9,10 +9,10 @@ GameMessage::StartCelebrationEffect(
duration: 0.0,
icon_id: 0,
main_text: lu!(""),
mixer_program: lu!(&b""[..]),
music_cue: lu!(&b""[..]),
path_node_name: lu!(&b""[..]),
sound_guid: lu!(&b""[..]),
mixer_program: lu!(b""),
music_cue: lu!(b""),
path_node_name: lu!(b""),
sound_guid: lu!(b""),
sub_text: lu!(""),
},
)

View File

@@ -1,6 +1,6 @@
GameMessage::StopFxEffect(
StopFxEffect {
kill_immediate: false,
name: lu!(&b"BrickFadeUpVisCompleteEffect"[..]),
name: lu!(b"BrickFadeUpVisCompleteEffect"),
},
)

View File

@@ -7,6 +7,6 @@ GameMessage::UiMessageServerToSingleClient(
"string": "string",
"array": amf3! ["inner", "array", true],
},
message_name: lu!(&b"QueueChoiceBox"[..]),
message_name: lu!(b"QueueChoiceBox"),
},
)

View File

@@ -8,6 +8,6 @@ GameMessage::PropertyEntranceSync(
reputation_time: 0,
sort_method: 5,
start_index: 0,
filter_text: lu!(&b""[..]),
filter_text: lu!(b""),
},
)

View File

@@ -1,8 +1,8 @@
GameMessage::ReportBug(
ReportBug {
body: lu!("code's haunted"),
client_version: lu!(&b"1.10.64"[..]),
other_player_id: lu!(&b"0"[..]),
selection: lu!(&b"%[UI_HELP_IN_GAME]"[..]),
client_version: lu!(b"1.10.64"),
other_player_id: lu!(b"0"),
selection: lu!(b"%[UI_HELP_IN_GAME]"),
},
)

View File

@@ -1,7 +1,7 @@
GameMessage::SetMissionTypeState(
SetMissionTypeState {
state: MissionLockState::New,
mission_subtype: lu!(&b""[..]),
mission_type: lu!(&b"Build"[..]),
mission_subtype: lu!(b""),
mission_type: lu!(b"Build"),
},
)

View File

@@ -102,6 +102,10 @@ impl From<&[u8]> for LnvValue {
fn from(val: &[u8]) -> Self { LnvValue::String(val.try_into().unwrap()) }
}
impl<const N: usize> From<&[u8; N]> for LnvValue {
fn from(val: &[u8; N]) -> Self { LnvValue::String(val.try_into().unwrap()) }
}
/// A hash map with values being one of multiple possible types.
#[derive(PartialEq)]
pub struct LuNameValue(HashMap<LuVarWString<u32>, LnvValue>);