• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

adierking / unplug / 16555866747

27 Jul 2025 09:53PM UTC coverage: 77.137%. First build
16555866747

push

github

adierking
cli: Move script dump commands into debug

43 of 139 new or added lines in 2 files covered. (30.94%)

20348 of 26379 relevant lines covered (77.14%)

1083026.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/unplug-cli/src/commands/debug.rs
1
use crate::args::debug::*;
2

3
use crate::common::find_stage_file;
4
use crate::context::Context;
5
use crate::io::OutputRedirect;
6

7
use anyhow::Result;
8
use log::info;
9
use std::fs::{self, File};
10
use std::io::{BufWriter, Write};
11
use std::path::Path;
12
use std::time::Instant;
13
use unplug::data::{self, Resource};
14
use unplug::event::{Block, Script};
15
use unplug::globals::{GlobalsBuilder, Libs};
16
use unplug::stage::Stage;
17

18
/// The `debug rebuild-scripts` CLI command.
19
fn command_rebuild_scripts(ctx: Context) -> Result<()> {
×
20
    let mut ctx = ctx.open_read_write()?;
×
21

22
    info!("Reading script globals");
×
23
    let mut globals = ctx.read_globals()?;
×
24
    let libs = globals.read_libs()?;
×
25

26
    let mut stages = vec![];
×
NEW
27
    for id in data::Stage::iter() {
×
28
        info!("Reading {}", id.file_name());
×
29
        let stage = ctx.read_stage(&libs, id)?;
×
30
        stages.push((id, stage));
×
31
    }
32

33
    info!("Rebuilding script globals");
×
34
    let mut update = ctx.begin_update();
×
35
    update = update.write_globals(GlobalsBuilder::new().base(&mut globals).libs(&libs))?;
×
36
    for (id, stage) in stages {
×
37
        info!("Rebuilding {}", id.file_name());
×
38
        update = update.write_stage(id, &stage)?;
×
39
    }
40

41
    info!("Updating game files");
×
42
    update.commit()?;
×
43
    Ok(())
×
44
}
×
45

NEW
46
fn do_dump_libs(libs: &Libs, flags: &DumpFlags, mut out: impl Write) -> Result<()> {
×
NEW
47
    for (i, id) in libs.entry_points.iter().enumerate() {
×
NEW
48
        writeln!(out, "lib[{}]: {:?}", i, id)?;
×
49
    }
NEW
50
    dump_script(&libs.script, flags, out)?;
×
NEW
51
    Ok(())
×
NEW
52
}
×
53

NEW
54
fn do_dump_stage(stage: &Stage, flags: &DumpFlags, mut out: impl Write) -> Result<()> {
×
NEW
55
    for (i, object) in stage.objects.iter().enumerate() {
×
NEW
56
        writeln!(out, "obj[{}]: {:?}", i, object)?;
×
57
    }
NEW
58
    writeln!(out)?;
×
59

NEW
60
    if flags.dump_unknown {
×
NEW
61
        writeln!(out, "settings: {:?}", stage.settings)?;
×
NEW
62
        writeln!(out)?;
×
NEW
63
        for (i, unk) in stage.unk_28.iter().enumerate() {
×
NEW
64
            writeln!(out, "unk28[{}]: {:?}", i, unk)?;
×
65
        }
NEW
66
        writeln!(out)?;
×
NEW
67
        for (i, unk) in stage.unk_2c.iter().enumerate() {
×
NEW
68
            writeln!(out, "unk2C[{}]: {:?}", i, unk)?;
×
69
        }
NEW
70
        writeln!(out)?;
×
NEW
71
        for (i, unk) in stage.unk_30.iter().enumerate() {
×
NEW
72
            writeln!(out, "unk30[{}]: {:?}", i, unk)?;
×
73
        }
NEW
74
        writeln!(out)?;
×
NEW
75
    }
×
76

NEW
77
    writeln!(out, "on_prologue: {:?}", stage.on_prologue)?;
×
NEW
78
    writeln!(out, "on_startup: {:?}", stage.on_startup)?;
×
NEW
79
    writeln!(out, "on_dead: {:?}", stage.on_dead)?;
×
NEW
80
    writeln!(out, "on_pose: {:?}", stage.on_pose)?;
×
NEW
81
    writeln!(out, "on_time_cycle: {:?}", stage.on_time_cycle)?;
×
NEW
82
    writeln!(out, "on_time_up: {:?}", stage.on_time_up)?;
×
83

NEW
84
    dump_script(&stage.script, flags, out)?;
×
NEW
85
    Ok(())
×
NEW
86
}
×
87

88
fn dump_script(script: &Script, flags: &DumpFlags, mut out: impl Write) -> Result<()> {
NEW
89
    write!(out, "\nDATA\n\n")?;
×
NEW
90
    if flags.no_offsets {
×
NEW
91
        writeln!(out, "id   value")?;
×
92
    } else {
NEW
93
        writeln!(out, "off   id   value")?;
×
94
    }
NEW
95
    for (location, block) in script.blocks_ordered() {
×
NEW
96
        if let Block::Data(data) = block {
×
NEW
97
            if flags.no_offsets {
×
NEW
98
                writeln!(out, "{:<4} {:?}", location.id.index(), data)?;
×
99
            } else {
NEW
100
                writeln!(out, "{:<5x} {:<4} {:?}", location.offset, location.id.index(), data)?;
×
101
            }
NEW
102
        }
×
103
    }
104

NEW
105
    write!(out, "\nCODE\n\n")?;
×
NEW
106
    if flags.no_offsets {
×
NEW
107
        writeln!(out, "id   command")?;
×
108
    } else {
NEW
109
        writeln!(out, "off   id   command")?;
×
110
    }
NEW
111
    for (location, command) in script.commands_ordered() {
×
NEW
112
        let block = location.block;
×
NEW
113
        if flags.no_offsets {
×
NEW
114
            writeln!(out, "{:<4} {:?}", block.id.index(), command)?;
×
115
        } else {
NEW
116
            writeln!(out, "{:<5x} {:<4} {:?}", block.offset, block.id.index(), command)?;
×
117
        }
118
    }
NEW
119
    Ok(())
×
NEW
120
}
×
121

122
/// The `debug dump-script` CLI command.
NEW
123
pub fn command_dump_script(ctx: Context, args: DumpArgs) -> Result<()> {
×
NEW
124
    let mut ctx = ctx.open_read()?;
×
NEW
125
    let out = BufWriter::new(OutputRedirect::new(args.output)?);
×
NEW
126
    let file = find_stage_file(&mut ctx, &args.stage)?;
×
NEW
127
    info!("Reading script globals");
×
NEW
128
    let libs = ctx.read_globals()?.read_libs()?;
×
NEW
129
    info!("Dumping {}", ctx.query_file(&file)?.name);
×
NEW
130
    let stage = ctx.read_stage_file(&libs, &file)?;
×
NEW
131
    do_dump_stage(&stage, &args.flags, out)?;
×
NEW
132
    Ok(())
×
NEW
133
}
×
134

135
/// The `debug dump-script globals` CLI command.
NEW
136
pub fn command_dump_script_globals(ctx: Context, args: DumpArgs) -> Result<()> {
×
NEW
137
    let mut ctx = ctx.open_read()?;
×
NEW
138
    let out = BufWriter::new(OutputRedirect::new(args.output)?);
×
NEW
139
    info!("Dumping script globals");
×
NEW
140
    let libs = ctx.read_globals()?.read_libs()?;
×
NEW
141
    do_dump_libs(&libs, &args.flags, out)
×
NEW
142
}
×
143

144
/// The `debug dump-all-scripts` CLI command.
NEW
145
pub fn command_dump_all_scripts(ctx: Context, args: DumpAllArgs) -> Result<()> {
×
NEW
146
    let start_time = Instant::now();
×
NEW
147
    let mut ctx = ctx.open_read()?;
×
148

NEW
149
    info!("Dumping script globals");
×
NEW
150
    fs::create_dir_all(&args.output)?;
×
NEW
151
    let libs = ctx.read_globals()?.read_libs()?;
×
NEW
152
    let libs_out = File::create(Path::join(&args.output, "globals.txt"))?;
×
NEW
153
    do_dump_libs(&libs, &args.flags, BufWriter::new(libs_out))?;
×
154

NEW
155
    for id in data::Stage::iter() {
×
NEW
156
        info!("Dumping {}", id.file_name());
×
NEW
157
        let stage = ctx.read_stage(&libs, id)?;
×
NEW
158
        let stage_out = File::create(Path::join(&args.output, format!("{}.txt", id.name())))?;
×
NEW
159
        do_dump_stage(&stage, &args.flags, BufWriter::new(stage_out))?;
×
160
    }
161

NEW
162
    info!("Dumping finished in {:?}", start_time.elapsed());
×
NEW
163
    Ok(())
×
NEW
164
}
×
165

166
/// The `debug` CLI command.
167
pub fn command(ctx: Context, command: Subcommand) -> Result<()> {
168
    match command {
×
169
        Subcommand::RebuildScripts => command_rebuild_scripts(ctx),
×
NEW
170
        Subcommand::DumpScript(args) if args.stage == "globals" => {
×
NEW
171
            command_dump_script_globals(ctx, args)
×
172
        }
NEW
173
        Subcommand::DumpScript(args) => command_dump_script(ctx, args),
×
NEW
174
        Subcommand::DumpAllScripts(args) => command_dump_all_scripts(ctx, args),
×
175
    }
176
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc