|
6 | 6 | #include "CoreDefs.h" |
7 | 7 | #include "LuaTools.h" |
8 | 8 | #include "PluginManager.h" |
| 9 | +#include "RemoteTools.h" |
9 | 10 |
|
10 | 11 | #include "modules/Gui.h" |
11 | 12 | #include "modules/World.h" |
@@ -392,4 +393,189 @@ namespace DFHack |
392 | 393 | return CR_OK; |
393 | 394 | } |
394 | 395 |
|
| 396 | + command_result Commands::clear(color_ostream& con, Core& core, const std::string& first, const std::vector<std::string>& parts) |
| 397 | + { |
| 398 | + if (con.can_clear()) |
| 399 | + { |
| 400 | + con.clear(); |
| 401 | + return CR_OK; |
| 402 | + } |
| 403 | + else |
| 404 | + { |
| 405 | + con.printerr("No console to clear, or this console does not support clearing.\n"); |
| 406 | + return CR_NEEDS_CONSOLE; |
| 407 | + } |
| 408 | + } |
| 409 | + |
| 410 | + command_result Commands::kill_lua(color_ostream& con, Core& core, const std::string& first, const std::vector<std::string>& parts) |
| 411 | + { |
| 412 | + bool force = std::ranges::any_of(parts, [] (const std::string& part) { return part == "force"; }); |
| 413 | + if (!Lua::Interrupt(force)) |
| 414 | + { |
| 415 | + con.printerr( |
| 416 | + "Failed to register hook. This can happen if you have" |
| 417 | + " lua profiling or coverage monitoring enabled. Use" |
| 418 | + " 'kill-lua force' to force, but this may disable" |
| 419 | + " profiling and coverage monitoring.\n"); |
| 420 | + return CR_FAILURE; |
| 421 | + } |
| 422 | + return CR_OK; |
| 423 | + } |
| 424 | + |
| 425 | + command_result Commands::script(color_ostream& con, Core& core, const std::string& first, const std::vector<std::string>& parts) |
| 426 | + { |
| 427 | + if (parts.size() == 1) |
| 428 | + { |
| 429 | + core.loadScriptFile(con, std::filesystem::weakly_canonical(std::filesystem::path{parts[0]}), false); |
| 430 | + return CR_OK; |
| 431 | + } |
| 432 | + else |
| 433 | + { |
| 434 | + con << "Usage:" << std::endl |
| 435 | + << " script <filename>" << std::endl; |
| 436 | + return CR_WRONG_USAGE; |
| 437 | + } |
| 438 | + } |
| 439 | + |
| 440 | + command_result Commands::show(color_ostream& con, Core& core, const std::string& first, const std::vector<std::string>& parts) |
| 441 | + { |
| 442 | + if (!core.getConsole().show()) |
| 443 | + { |
| 444 | + con.printerr("Could not show console\n"); |
| 445 | + return CR_FAILURE; |
| 446 | + } |
| 447 | + return CR_OK; |
| 448 | + } |
| 449 | + |
| 450 | + command_result Commands::hide(color_ostream& con, Core& core, const std::string& first, const std::vector<std::string>& parts) |
| 451 | + { |
| 452 | + if (!core.getConsole().hide()) |
| 453 | + { |
| 454 | + con.printerr("Could not hide console\n"); |
| 455 | + return CR_FAILURE; |
| 456 | + } |
| 457 | + return CR_OK; |
| 458 | + } |
| 459 | + |
| 460 | + command_result Commands::sc_script(color_ostream& con, Core& core, const std::string& first, const std::vector<std::string>& parts) |
| 461 | + { |
| 462 | + if (parts.empty() || parts[0] == "help" || parts[0] == "?") |
| 463 | + { |
| 464 | + con << "Usage: sc-script add|remove|list|help SC_EVENT [path-to-script] [...]" << std::endl; |
| 465 | + con << "Valid event names (SC_ prefix is optional):" << std::endl; |
| 466 | + for (int i = SC_WORLD_LOADED; i <= SC_UNPAUSED; i++) |
| 467 | + { |
| 468 | + std::string name = sc_event_name((state_change_event)i); |
| 469 | + if (name != "SC_UNKNOWN") |
| 470 | + con << " " << name << std::endl; |
| 471 | + } |
| 472 | + return CR_OK; |
| 473 | + } |
| 474 | + else if (parts[0] == "list") |
| 475 | + { |
| 476 | + std::string event_name = parts.size() >= 2 ? parts[1] : ""; |
| 477 | + if (event_name.size() && sc_event_id(event_name) == SC_UNKNOWN) |
| 478 | + { |
| 479 | + con << "Unrecognized event name: " << parts[1] << std::endl; |
| 480 | + return CR_WRONG_USAGE; |
| 481 | + } |
| 482 | + for (const auto& state_script : core.getStateChangeScripts()) |
| 483 | + { |
| 484 | + if (!parts[1].size() || (state_script.event == sc_event_id(parts[1]))) |
| 485 | + { |
| 486 | + con.print("%s (%s): %s%s\n", sc_event_name(state_script.event).c_str(), |
| 487 | + state_script.save_specific ? "save-specific" : "global", |
| 488 | + state_script.save_specific ? "<save folder>/raw/" : "<DF folder>/", |
| 489 | + state_script.path.c_str()); |
| 490 | + } |
| 491 | + } |
| 492 | + return CR_OK; |
| 493 | + } |
| 494 | + else if (parts[0] == "add") |
| 495 | + { |
| 496 | + if (parts.size() < 3 || (parts.size() >= 4 && parts[3] != "-save")) |
| 497 | + { |
| 498 | + con << "Usage: sc-script add EVENT path-to-script [-save]" << std::endl; |
| 499 | + return CR_WRONG_USAGE; |
| 500 | + } |
| 501 | + state_change_event evt = sc_event_id(parts[1]); |
| 502 | + if (evt == SC_UNKNOWN) |
| 503 | + { |
| 504 | + con << "Unrecognized event: " << parts[1] << std::endl; |
| 505 | + return CR_FAILURE; |
| 506 | + } |
| 507 | + bool save_specific = (parts.size() >= 4 && parts[3] == "-save"); |
| 508 | + StateChangeScript script(evt, parts[2], save_specific); |
| 509 | + for (const auto& state_script : core.getStateChangeScripts()) |
| 510 | + { |
| 511 | + if (script == state_script) |
| 512 | + { |
| 513 | + con << "Script already registered" << std::endl; |
| 514 | + return CR_FAILURE; |
| 515 | + } |
| 516 | + } |
| 517 | + core.addStateChangeScript(script); |
| 518 | + return CR_OK; |
| 519 | + } |
| 520 | + else if (parts[0] == "remove") |
| 521 | + { |
| 522 | + if (parts.size() < 3 || (parts.size() >= 4 && parts[3] != "-save")) |
| 523 | + { |
| 524 | + con << "Usage: sc-script remove EVENT path-to-script [-save]" << std::endl; |
| 525 | + return CR_WRONG_USAGE; |
| 526 | + } |
| 527 | + state_change_event evt = sc_event_id(parts[1]); |
| 528 | + if (evt == SC_UNKNOWN) |
| 529 | + { |
| 530 | + con << "Unrecognized event: " << parts[1] << std::endl; |
| 531 | + return CR_FAILURE; |
| 532 | + } |
| 533 | + bool save_specific = (parts.size() >= 4 && parts[3] == "-save"); |
| 534 | + StateChangeScript tmp(evt, parts[2], save_specific); |
| 535 | + if (core.removeStateChangeScript(tmp)) |
| 536 | + { |
| 537 | + return CR_OK; |
| 538 | + } |
| 539 | + else |
| 540 | + { |
| 541 | + con << "Unrecognized script" << std::endl; |
| 542 | + return CR_FAILURE; |
| 543 | + } |
| 544 | + } |
| 545 | + else |
| 546 | + { |
| 547 | + con << "Usage: sc-script add|remove|list|help SC_EVENT [path-to-script] [...]" << std::endl; |
| 548 | + return CR_WRONG_USAGE; |
| 549 | + } |
| 550 | + } |
| 551 | + |
| 552 | + command_result Commands::dump_rpc(color_ostream& con, Core& core, const std::string& first, const std::vector<std::string>& parts) |
| 553 | + { |
| 554 | + if (parts.size() == 1) |
| 555 | + { |
| 556 | + std::ofstream file(parts[0]); |
| 557 | + CoreService coreSvc; |
| 558 | + coreSvc.dumpMethods(file); |
| 559 | + |
| 560 | + for (auto& it : *core.getPluginManager()) |
| 561 | + { |
| 562 | + Plugin* plug = it.second; |
| 563 | + if (!plug) |
| 564 | + continue; |
| 565 | + |
| 566 | + std::unique_ptr<RPCService> svc(plug->rpc_connect(con)); |
| 567 | + if (!svc) |
| 568 | + continue; |
| 569 | + |
| 570 | + file << "// Plugin: " << plug->getName() << std::endl; |
| 571 | + svc->dumpMethods(file); |
| 572 | + } |
| 573 | + } |
| 574 | + else |
| 575 | + { |
| 576 | + con << "Usage: devel/dump-rpc \"filename\"" << std::endl; |
| 577 | + return CR_WRONG_USAGE; |
| 578 | + } |
| 579 | + return CR_OK; |
| 580 | + } |
395 | 581 | } |
0 commit comments