18 return CHANGE_DIRECTORY;
30 return COPY_FILE_IF_EXISTS;
42 return "Change Directory";
50 return "Copy File If It Exists";
57 return getSpecialDisplayNameFor(this->special);
59 return this->executable;
66 FileStream reader{path};
70 if (
auto binStr = reader.seek_in(0).read_string(10); binStr ==
"Worldcraft") {
73 auto kvStr = reader.seek_in(0).read_string(19);
75 if (kvStr ==
"\"command sequences\"") {
99CmdSeq::operator bool()
const {
100 return this->type != Type::INVALID;
124 FileStream reader{path};
129 reader.seek_in(31).read(this->
version);
131 const auto sequenceCount = reader.read<uint32_t>();
132 for (uint32_t s = 0; s < sequenceCount; s++) {
133 auto& [seqName, seqCommands] = this->
sequences.emplace_back();
134 seqName = reader.read_string(128);
136 const auto commandCount = reader.read<uint32_t>();
137 for (uint32_t c = 0; c < commandCount; c++) {
138 auto& [enabled, special, executable, arguments, ensureFileExists, pathToTheoreticallyExistingFile, useProcessWindow, waitForKeypress] = seqCommands.emplace_back();
139 enabled = reader.read<int32_t>() & 0xFF;
144 executable = reader.read_string(260);
145 arguments = reader.read_string(260);
146 reader.skip_in<int32_t>();
147 ensureFileExists = reader.read<int32_t>();
148 pathToTheoreticallyExistingFile = reader.read_string(260);
149 useProcessWindow = reader.read<int32_t>();
151 waitForKeypress = reader.read<int32_t>();
161 for (
const auto& kvSequence : cmdSeq[
"Command Sequences"].getChildren()) {
162 auto& [seqName, seqCommands] = this->
sequences.emplace_back();
163 seqName = kvSequence.getKey();
165 for (
const auto& kvCommand : kvSequence.getChildren()) {
166 auto& [enabled, special, executable, arguments, ensureFileExists, pathToTheoreticallyExistingFile, useProcessWindow, waitForKeypress] = seqCommands.emplace_back();
168 const auto specialCmd = kvCommand[
"special_cmd"].getValue();
170 string::toInt(specialCmd,
reinterpret_cast<std::underlying_type_t<Command::Special>&
>(special));
175 special = ::specialCmdFromString(specialCmd);
177 executable = kvCommand[
"run"].getValue();
178 arguments = kvCommand[
"params"].getValue();
179 string::toBool(kvCommand[
"ensure_check"].getValue(), ensureFileExists);
180 pathToTheoreticallyExistingFile = kvCommand[
"ensure_fn"].getValue();
181 string::toBool(kvCommand[
"use_process_wnd"].getValue(), useProcessWindow);
196 std::vector<std::byte> out;
197 BufferStream writer{out};
200 .write(
"Worldcraft Command Sequences\r\n\x1a", 31)
204 for (
const auto& [seqName, seqCommands] : this->
getSequences()) {
206 .write(seqName,
true, 128)
207 .write<uint32_t>(seqCommands.size());
209 for (
const auto& [enabled, special, executable, arguments, ensureFileExists, pathToTheoreticallyExistingFile, useProcessWindow, waitForKeypress] : seqCommands) {
211 .write<uint32_t>(enabled)
213 .write(executable,
true, 260)
214 .write(arguments,
true, 260)
215 .write<uint32_t>(
true)
216 .write<uint32_t>(ensureFileExists)
217 .write(pathToTheoreticallyExistingFile,
true, 260)
218 .write<uint32_t>(useProcessWindow);
221 writer.write<uint32_t>(waitForKeypress);
226 out.resize(writer.size());
232 auto& kvFile = kv.
addChild(
"Command Sequences");
233 for (
const auto& [seqName, seqCommands] : this->
getSequences()) {
234 auto& kvSequence = kvFile.
addChild(seqName);
235 for (
int i = 1; i <= seqCommands.size(); i++) {
236 const auto& [enabled, special, executable, arguments, ensureFileExists, pathToTheoreticallyExistingFile, useProcessWindow, waitForKeypress] = seqCommands[i - 1];
237 auto& kvCommand = kvSequence.
addChild(std::to_string(i));
238 kvCommand[
"enabled"] = enabled;
239 kvCommand[
"special_cmd"] =
static_cast<int>(special);
240 kvCommand[
"run"] = executable;
241 kvCommand[
"params"] = arguments;
242 kvCommand[
"ensure_check"] = ensureFileExists;
243 kvCommand[
"ensure_fn"] = pathToTheoreticallyExistingFile;
244 kvCommand[
"use_process_wnd"] = useProcessWindow;
245 kvCommand[
"no_wait"] = waitForKeypress;
249 const auto kvStr = kv.
bake();
250 std::vector<std::byte> out;
251 out.resize(kvStr.length());
252 std::memcpy(out.data(), kvStr.data(), kvStr.length());
257 switch (this->
type) {
270 FileStream writer{path};
274 writer.seek_out(0).write(this->
bake());
KV1ElementWritable & addChild(std::string_view key_, V value_={}, std::string_view conditional_="")
std::string readFileText(const std::string &filepath, std::size_t startOffset=0)
bool isNumber(char c)
If a char is a numerical character (0-9).
std::from_chars_result toBool(std::string_view number, bool &out, int base=10)
std::from_chars_result toInt(std::string_view number, std::integral auto &out, int base=10)
bool iequals(std::string_view s1, std::string_view s2)
void toLower(std::string &input)