mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-26 21:57:08 +08:00
fux bug
This commit is contained in:
@@ -559,7 +559,9 @@ impl<'a> TryFrom<&'a YSTBArg> for YSTBArgTmp {
|
|||||||
data = &data[3..];
|
data = &data[3..];
|
||||||
} else {
|
} else {
|
||||||
if list.is_empty() {
|
if list.is_empty() {
|
||||||
if !data.contains(&0) && let Ok(s) = decode_to_string(value.encoding, data, true) {
|
if !data.contains(&0)
|
||||||
|
&& let Ok(s) = decode_to_string(value.encoding, data, true)
|
||||||
|
{
|
||||||
list.push(YSTBArgDat::String { s });
|
list.push(YSTBArgDat::String { s });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -867,7 +869,9 @@ impl<'a> std::fmt::Debug for YSTBArgData<'a> {
|
|||||||
data = &data[3..];
|
data = &data[3..];
|
||||||
} else {
|
} else {
|
||||||
if is_first {
|
if is_first {
|
||||||
if !data.contains(&0) && let Ok(s) = decode_to_string(self.1, &data, true) {
|
if !data.contains(&0)
|
||||||
|
&& let Ok(s) = decode_to_string(self.1, &data, true)
|
||||||
|
{
|
||||||
f.write_str(&s)?;
|
f.write_str(&s)?;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1276,6 +1280,17 @@ impl<'a> serde::Serialize for YSTBInstSer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build PUSHSTRING data: `M` + (content_len + 2) + `"` + content + `"`
|
||||||
|
fn make_pushstring_data(content: &[u8]) -> Vec<u8> {
|
||||||
|
let mut new_data = Vec::with_capacity(5 + content.len());
|
||||||
|
new_data.push(b'M');
|
||||||
|
new_data.extend_from_slice(&((content.len() + 2) as u16).to_le_bytes());
|
||||||
|
new_data.push(b'"');
|
||||||
|
new_data.extend_from_slice(content);
|
||||||
|
new_data.push(b'"');
|
||||||
|
new_data
|
||||||
|
}
|
||||||
|
|
||||||
impl Script for YSTB {
|
impl Script for YSTB {
|
||||||
fn default_output_script_type(&self) -> OutputScriptType {
|
fn default_output_script_type(&self) -> OutputScriptType {
|
||||||
OutputScriptType::Json
|
OutputScriptType::Json
|
||||||
@@ -1343,7 +1358,9 @@ impl Script for YSTB {
|
|||||||
}
|
}
|
||||||
} else if meta.name == "GOSUB" && code.arg_count >= 2 {
|
} else if meta.name == "GOSUB" && code.arg_count >= 2 {
|
||||||
let arg0 = &code.args[0];
|
let arg0 = &code.args[0];
|
||||||
let name = format!("{:?}", &YSTBArgData(&arg0.data, arg0.encoding)).trim_matches('"').to_lowercase();
|
let name = format!("{:?}", &YSTBArgData(&arg0.data, arg0.encoding))
|
||||||
|
.trim_matches('"')
|
||||||
|
.to_lowercase();
|
||||||
if name == "es.sel.set" {
|
if name == "es.sel.set" {
|
||||||
for arg in &code.args[1..] {
|
for arg in &code.args[1..] {
|
||||||
if arg.data.starts_with(PUSHSTRING_TYPE) {
|
if arg.data.starts_with(PUSHSTRING_TYPE) {
|
||||||
@@ -1393,9 +1410,10 @@ impl Script for YSTB {
|
|||||||
let mut inst_data: Vec<(YSTBInstBase, Vec<(YSTBArgBase, Vec<u8>)>)> = Vec::new();
|
let mut inst_data: Vec<(YSTBInstBase, Vec<(YSTBArgBase, Vec<u8>)>)> = Vec::new();
|
||||||
|
|
||||||
for code in self.data.insts.iter() {
|
for code in self.data.insts.iter() {
|
||||||
let meta = self.com.opcodes.get(code.opcode as usize).ok_or_else(|| {
|
let meta =
|
||||||
anyhow::anyhow!("Failed to find op {:x}'s metadata", code.opcode)
|
self.com.opcodes.get(code.opcode as usize).ok_or_else(|| {
|
||||||
})?;
|
anyhow::anyhow!("Failed to find op {:x}'s metadata", code.opcode)
|
||||||
|
})?;
|
||||||
|
|
||||||
// Default: copy all args as-is
|
// Default: copy all args as-is
|
||||||
let mut new_args: Vec<(YSTBArgBase, Vec<u8>)> = code
|
let mut new_args: Vec<(YSTBArgBase, Vec<u8>)> = code
|
||||||
@@ -1408,9 +1426,9 @@ impl Script for YSTB {
|
|||||||
if code.arg_count == 1 {
|
if code.arg_count == 1 {
|
||||||
let arg = &code.args[0];
|
let arg = &code.args[0];
|
||||||
if arg.typ == 0 && arg.size > 0 {
|
if arg.typ == 0 && arg.size > 0 {
|
||||||
let mut msg = messages_iter.next().ok_or_else(|| {
|
let mut msg = messages_iter
|
||||||
anyhow::anyhow!("No more messages to import")
|
.next()
|
||||||
})?;
|
.ok_or_else(|| anyhow::anyhow!("No more messages to import"))?;
|
||||||
if let Some(table) = replacement {
|
if let Some(table) = replacement {
|
||||||
for (from, to) in &table.map {
|
for (from, to) in &table.map {
|
||||||
msg.message = msg.message.replace(from, to);
|
msg.message = msg.message.replace(from, to);
|
||||||
@@ -1441,40 +1459,33 @@ impl Script for YSTB {
|
|||||||
if arg.data.starts_with(PUSHSTRING_TYPE) {
|
if arg.data.starts_with(PUSHSTRING_TYPE) {
|
||||||
let len = u16::from_le_bytes([arg.data[1], arg.data[2]]);
|
let len = u16::from_le_bytes([arg.data[1], arg.data[2]]);
|
||||||
if len as u32 + 3 == arg.size {
|
if len as u32 + 3 == arg.size {
|
||||||
let mut msg = messages_iter.next().ok_or_else(|| {
|
let mut msg = messages_iter
|
||||||
anyhow::anyhow!("No more messages to import")
|
.next()
|
||||||
})?;
|
.ok_or_else(|| anyhow::anyhow!("No more messages to import"))?;
|
||||||
if let Some(table) = replacement {
|
if let Some(table) = replacement {
|
||||||
for (from, to) in &table.map {
|
for (from, to) in &table.map {
|
||||||
msg.message = msg.message.replace(from, to);
|
msg.message = msg.message.replace(from, to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let d = encode_string(encoding, &msg.message, true)?;
|
let d = encode_string(encoding, &msg.message, true)?;
|
||||||
let mut new_data = Vec::with_capacity(3 + d.len());
|
new_args[0].1 = make_pushstring_data(&d);
|
||||||
new_data.push(b'M');
|
|
||||||
new_data.extend_from_slice(&(d.len() as u16).to_le_bytes());
|
|
||||||
new_data.extend_from_slice(&d);
|
|
||||||
new_args[0].1 = new_data;
|
|
||||||
new_args[0].0.size = new_args[0].1.len() as u32;
|
new_args[0].0.size = new_args[0].1.len() as u32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if meta.name == "GOSUB" && code.arg_count >= 2 {
|
} else if meta.name == "GOSUB" && code.arg_count >= 2 {
|
||||||
let arg0 = &code.args[0];
|
let arg0 = &code.args[0];
|
||||||
let name = format!(
|
let name = format!("{:?}", &YSTBArgData(&arg0.data, arg0.encoding))
|
||||||
"{:?}",
|
.trim_matches('"')
|
||||||
&YSTBArgData(&arg0.data, arg0.encoding)
|
.to_lowercase();
|
||||||
)
|
|
||||||
.trim_matches('"')
|
|
||||||
.to_lowercase();
|
|
||||||
if name == "es.sel.set" {
|
if name == "es.sel.set" {
|
||||||
for arg_pair in new_args.iter_mut().skip(1) {
|
for arg_pair in new_args.iter_mut().skip(1) {
|
||||||
let data = &arg_pair.1;
|
let data = &arg_pair.1;
|
||||||
if data.starts_with(PUSHSTRING_TYPE) {
|
if data.starts_with(PUSHSTRING_TYPE) {
|
||||||
let slen = u16::from_le_bytes([data[1], data[2]]);
|
let slen = u16::from_le_bytes([data[1], data[2]]);
|
||||||
if slen as u32 + 3 == arg_pair.0.size {
|
if slen as u32 + 3 == arg_pair.0.size {
|
||||||
let mut msg = messages_iter.next().ok_or_else(|| {
|
let mut msg = messages_iter
|
||||||
anyhow::anyhow!("No more messages to import")
|
.next()
|
||||||
})?;
|
.ok_or_else(|| anyhow::anyhow!("No more messages to import"))?;
|
||||||
if let Some(table) = replacement {
|
if let Some(table) = replacement {
|
||||||
for (from, to) in &table.map {
|
for (from, to) in &table.map {
|
||||||
msg.message = msg.message.replace(from, to);
|
msg.message = msg.message.replace(from, to);
|
||||||
@@ -1482,13 +1493,7 @@ impl Script for YSTB {
|
|||||||
}
|
}
|
||||||
if !msg.message.is_empty() {
|
if !msg.message.is_empty() {
|
||||||
let d = encode_string(encoding, &msg.message, true)?;
|
let d = encode_string(encoding, &msg.message, true)?;
|
||||||
let mut new_data = Vec::with_capacity(3 + d.len());
|
arg_pair.1 = make_pushstring_data(&d);
|
||||||
new_data.push(b'M');
|
|
||||||
new_data.extend_from_slice(
|
|
||||||
&(d.len() as u16).to_le_bytes(),
|
|
||||||
);
|
|
||||||
new_data.extend_from_slice(&d);
|
|
||||||
arg_pair.1 = new_data;
|
|
||||||
arg_pair.0.size = arg_pair.1.len() as u32;
|
arg_pair.0.size = arg_pair.1.len() as u32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1500,17 +1505,18 @@ impl Script for YSTB {
|
|||||||
if arg1.data.starts_with(PUSHSTRING_TYPE) {
|
if arg1.data.starts_with(PUSHSTRING_TYPE) {
|
||||||
let slen = u16::from_le_bytes([arg1.data[1], arg1.data[2]]);
|
let slen = u16::from_le_bytes([arg1.data[1], arg1.data[2]]);
|
||||||
if slen as u32 + 3 == arg1.size {
|
if slen as u32 + 3 == arg1.size {
|
||||||
let decoded = decode_to_string(
|
let mut decoded = decode_to_string(
|
||||||
arg1.encoding,
|
arg1.encoding,
|
||||||
&arg1.data[3..arg1.size as usize - 1],
|
&arg1.data[4..arg1.size as usize - 1],
|
||||||
true,
|
true,
|
||||||
)?;
|
)?;
|
||||||
|
if let Some(table) = replacement {
|
||||||
|
for (from, to) in &table.map {
|
||||||
|
decoded = decoded.replace(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
let d = encode_string(encoding, &decoded, true)?;
|
let d = encode_string(encoding, &decoded, true)?;
|
||||||
let mut new_data = Vec::with_capacity(3 + d.len());
|
new_args[1].1 = make_pushstring_data(&d);
|
||||||
new_data.push(b'M');
|
|
||||||
new_data.extend_from_slice(&(d.len() as u16).to_le_bytes());
|
|
||||||
new_data.extend_from_slice(&d);
|
|
||||||
new_args[1].1 = new_data;
|
|
||||||
new_args[1].0.size = new_args[1].1.len() as u32;
|
new_args[1].0.size = new_args[1].1.len() as u32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1519,23 +1525,40 @@ impl Script for YSTB {
|
|||||||
if arg2.data.starts_with(PUSHSTRING_TYPE) {
|
if arg2.data.starts_with(PUSHSTRING_TYPE) {
|
||||||
let slen = u16::from_le_bytes([arg2.data[1], arg2.data[2]]);
|
let slen = u16::from_le_bytes([arg2.data[1], arg2.data[2]]);
|
||||||
if slen as u32 + 3 == arg2.size {
|
if slen as u32 + 3 == arg2.size {
|
||||||
let mut msg = messages_iter.next().ok_or_else(|| {
|
let mut msg = messages_iter
|
||||||
anyhow::anyhow!("No more messages to import")
|
.next()
|
||||||
})?;
|
.ok_or_else(|| anyhow::anyhow!("No more messages to import"))?;
|
||||||
if let Some(table) = replacement {
|
if let Some(table) = replacement {
|
||||||
for (from, to) in &table.map {
|
for (from, to) in &table.map {
|
||||||
msg.message = msg.message.replace(from, to);
|
msg.message = msg.message.replace(from, to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let d = encode_string(encoding, &msg.message, true)?;
|
let d = encode_string(encoding, &msg.message, true)?;
|
||||||
let mut new_data = Vec::with_capacity(3 + d.len());
|
new_args[2].1 = make_pushstring_data(&d);
|
||||||
new_data.push(b'M');
|
|
||||||
new_data.extend_from_slice(&(d.len() as u16).to_le_bytes());
|
|
||||||
new_data.extend_from_slice(&d);
|
|
||||||
new_args[2].1 = new_data;
|
|
||||||
new_args[2].0.size = new_args[2].1.len() as u32;
|
new_args[2].0.size = new_args[2].1.len() as u32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if name == "es.char.name.mark.set" && code.arg_count >= 2 {
|
||||||
|
// Re-encode arg[1] from original encoding to target encoding only
|
||||||
|
let arg1 = &code.args[1];
|
||||||
|
if arg1.data.starts_with(PUSHSTRING_TYPE) {
|
||||||
|
let slen = u16::from_le_bytes([arg1.data[1], arg1.data[2]]);
|
||||||
|
if slen as u32 + 3 == arg1.size {
|
||||||
|
let mut decoded = decode_to_string(
|
||||||
|
arg1.encoding,
|
||||||
|
&arg1.data[4..arg1.size as usize - 1],
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
if let Some(table) = replacement {
|
||||||
|
for (from, to) in &table.map {
|
||||||
|
decoded = decoded.replace(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let d = encode_string(encoding, &decoded, true)?;
|
||||||
|
new_args[1].1 = make_pushstring_data(&d);
|
||||||
|
new_args[1].0.size = new_args[1].1.len() as u32;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1573,9 +1596,10 @@ impl Script for YSTB {
|
|||||||
let bpos = f.pos as u32;
|
let bpos = f.pos as u32;
|
||||||
|
|
||||||
for (base, args) in inst_data.iter_mut() {
|
for (base, args) in inst_data.iter_mut() {
|
||||||
let meta = self.com.opcodes.get(base.opcode as usize).ok_or_else(|| {
|
let meta =
|
||||||
anyhow::anyhow!("Failed to find op {:x}'s metadata", base.opcode)
|
self.com.opcodes.get(base.opcode as usize).ok_or_else(|| {
|
||||||
})?;
|
anyhow::anyhow!("Failed to find op {:x}'s metadata", base.opcode)
|
||||||
|
})?;
|
||||||
|
|
||||||
for arg in args.iter_mut() {
|
for arg in args.iter_mut() {
|
||||||
arg.0.size = arg.1.len() as u32;
|
arg.0.size = arg.1.len() as u32;
|
||||||
@@ -1583,9 +1607,7 @@ impl Script for YSTB {
|
|||||||
cpos += 8;
|
cpos += 8;
|
||||||
|
|
||||||
if arg.0.size == 0
|
if arg.0.size == 0
|
||||||
|| (meta.name == "RETURNCODE"
|
|| (meta.name == "RETURNCODE" && arg.0.size == 1 && arg.1[0] == b'M')
|
||||||
&& arg.0.size == 1
|
|
||||||
&& arg.1[0] == b'M')
|
|
||||||
{
|
{
|
||||||
f.write_u32_at(cpos, 0)?;
|
f.write_u32_at(cpos, 0)?;
|
||||||
cpos += 4;
|
cpos += 4;
|
||||||
|
|||||||
Reference in New Issue
Block a user