Rigs of Rods 2026.01
Soft-body Physics Simulation
Loading...
Searching...
No Matches
ConsoleCmd.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2013-2020 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "Application.h"
23#include "Actor.h"
24#include "ActorManager.h"
25#include "CameraManager.h"
26#include "Character.h"
27#include "Console.h"
28#include "GameContext.h"
29#include "GfxScene.h"
30#include "GUIManager.h"
31#include "IGfxWater.h"
32#include "Language.h"
33#include "Network.h"
34#include "OverlayWrapper.h"
35#include "RoRnet.h"
36#include "RoRVersion.h"
37#include "ScriptEngine.h"
38#include "ServerScriptEngine.h"
39#include "Terrain.h"
41#include "Utils.h"
42
43#include <algorithm>
44#include <Ogre.h>
45#include <fmt/core.h>
46
48
49using namespace RoR;
50
53
54// -------------------------------------------------------------------------------------
55// Builtin console commands.
56
59
61{
62public:
63 GravityCmd(): ConsoleCmd("gravity", "[<number> or <constant>]", _L("Get or set terrain gravity. Constants: earth/moon/mars/jupiter.")) {}
64
65 void Run(Ogre::StringVector const& args) override
66 {
67 if (!this->CheckAppState(AppState::SIMULATION))
68 return;
69
70 Str<200> reply;
71 if (args.size() == 1)
72 {
73 reply << _L("Current gravity is: ") << App::GetGameContext()->GetTerrain()->getGravity();
74 }
75 else
76 {
77 if (args[1] == "earth") { App::GetGameContext()->GetTerrain()->setGravity(DEFAULT_GRAVITY); }
78 else if (args[1] == "moon") { App::GetGameContext()->GetTerrain()->setGravity(-1.62f); }
79 else if (args[1] == "mars") { App::GetGameContext()->GetTerrain()->setGravity(-3.711f); }
80 else if (args[1] == "jupiter") { App::GetGameContext()->GetTerrain()->setGravity(-24.8f); }
81 else { App::GetGameContext()->GetTerrain()->setGravity(PARSEREAL(args[1])); }
82
83 reply << _L("Gravity set to: ") << App::GetGameContext()->GetTerrain()->getGravity();
84 }
85
87 }
88};
89
91{
92public:
93 WaterlevelCmd(): ConsoleCmd("waterlevel", "[<number>]", _L("Get or set water level.")) {}
94
95 void Run(Ogre::StringVector const& args) override
96 {
97 if (!this->CheckAppState(AppState::SIMULATION))
98 return;
99
100 Str<200> reply;
101 Console::MessageType reply_type;
102 reply << m_name << ": ";
103 if (!App::GetGameContext()->GetTerrain()->getWater())
104 {
106 reply << _L("This terrain does not have water.");
107 }
108 else
109 {
111 if (args.size() > 1)
112 {
113 auto water = App::GetGameContext()->GetTerrain()->getWater();
114 float height = (args[1] == "default") ? App::GetGameContext()->GetTerrain()->getWaterHeight() : PARSEREAL(args[1]);
115 water->SetStaticWaterHeight(height);
116 }
117 reply << _L ("Water level set to: ") << App::GetGameContext()->GetTerrain()->getWater()->GetStaticWaterHeight();
118 }
120 }
121};
122
124{
125public:
126 TerrainheightCmd(): ConsoleCmd("terrainheight", "[]", _L("Get elevation of terrain at current position")) {}
127
128 void Run(Ogre::StringVector const& args) override
129 {
130 if (!this->CheckAppState(AppState::SIMULATION))
131 return;
132
133 ROR_ASSERT(App::GetGameContext()->GetTerrain());
134
135 Str<200> reply;
136 reply << m_name << ": ";
138 Ogre::Vector3 pos;
140 if (actor)
141 {
142 pos = actor->getPosition();
143
144 }
145 else
146 {
147 ROR_ASSERT(App::GetGameContext()->GetPlayerCharacter());
149 }
150 reply << _L("Terrain height at position: ")
151 << "x: " << pos.x << " z: " << pos.z << " = "
152 << App::GetGameContext()->GetTerrain()->getHeightAt(pos.x, pos.z);
154 }
155};
156
158{
159public:
160 SpawnobjectCmd(): ConsoleCmd("spawnobject", "<odef name>", _L("spawnobject - spawn a object at the player position")) {}
161
162 void Run(Ogre::StringVector const& args) override
163 {
164 if (!this->CheckAppState(AppState::SIMULATION))
165 return;
166
167 ROR_ASSERT(App::GetGameContext()->GetPlayerCharacter());
168 ROR_ASSERT(App::GetGameContext()->GetTerrain());
169
170 Str<200> reply;
171 reply << m_name << ": ";
172 Console::MessageType reply_type;
173
174 try
175 {
176 if (args.size() == 1)
177 {
179 reply << _L("Missing parameter: ") << m_usage;
180 }
181 else
182 {
183 Ogre::Vector3 pos = App::GetGameContext()->GetPlayerCharacter()->getPosition();
184 if (App::GetGameContext()->GetTerrain()->getObjectManager()->LoadTerrainObject(args[1], pos, Ogre::Vector3::ZERO, "Console", ""))
185 {
187 reply << _L("Spawned object at position: ") << "x: " << pos.x << " z: " << pos.z;
188 }
189 else
190 {
192 reply << _L("Could not spawn object");
193 }
194 }
195 }
196 catch (std::exception& e)
197 {
199 reply << e.what();
200 }
202 }
203};
204
205class LogCmd: public ConsoleCmd
206{
207public:
208 LogCmd(): ConsoleCmd("log", "[]", _L("log - toggles log output on the console")) {}
209
210 void Run(Ogre::StringVector const& args) override
211 {
212 Str<200> reply;
213 reply << m_name << ": ";
215
216 // switch to console logging
217 bool now_logging = !App::diag_log_console_echo->getBool();
218 const char* msg = (now_logging) ? " logging to console enabled" : " logging to console disabled";
219 reply << _L(msg);
221
223 }
224};
225
226class VerCmd: public ConsoleCmd
227{
228public:
229 VerCmd(): ConsoleCmd("ver", "[]", _L("ver - shows the Rigs of Rods version")) {}
230
231 void Run(Ogre::StringVector const& args) override
232 {
233 Str<200> reply;
234 reply << m_name << ": ";
236
237 reply << "Rigs of Rods " << ROR_VERSION_STRING
238 << " (" << RORNET_VERSION << ") ["
239 << ROR_BUILD_DATE << ", " << ROR_BUILD_TIME << "]";
240
242 }
243};
244
245class PosCmd: public ConsoleCmd
246{
247public:
248 PosCmd(): ConsoleCmd("pos", "[]", _L("pos - outputs the current position")) {}
249
250 void Run(Ogre::StringVector const& args) override
251 {
252 if (!this->CheckAppState(AppState::SIMULATION))
253 return;
254
255 Str<200> reply;
256 reply << m_name << ": ";
258
260 if (!b && App::GetGameContext()->GetPlayerCharacter())
261 {
262 Ogre::Vector3 pos = App::GetGameContext()->GetPlayerCharacter()->getPosition();
263 reply << _L("Character position: ") << "x: " << pos.x << " y: " << pos.y << " z: " << pos.z;
264 }
265 else if (b)
266 {
267 Ogre::Vector3 pos = b->getPosition();
268 reply << _L("Vehicle position: ") << "x: " << pos.x << " y: " << pos.y << " z: " << pos.z;
269 }
270
272 }
273};
274
275class GotoCmd: public ConsoleCmd
276{
277public:
278 GotoCmd(): ConsoleCmd("goto", "<x> <y> <z>", _L("goto <x> <y> <z> - jumps to the mentioned position")) {}
279
280 void Run(Ogre::StringVector const& args) override
281 {
282 if (!this->CheckAppState(AppState::SIMULATION))
283 return;
284
285 Str<200> reply;
286 reply << m_name << ": ";
287 Console::MessageType reply_type;
288
289 if (args.size() != 4)
290 {
291 reply_type = Console::CONSOLE_HELP;
292 reply <<_L("usage: goto x y z");
293 }
294 else
295 {
297 Ogre::Vector3 pos(PARSEREAL(args[1]), PARSEREAL(args[2]), PARSEREAL(args[3]));
298
300 if (!b && App::GetGameContext()->GetPlayerCharacter())
301 {
303 reply << _L("Character position set to: ") << "x: " << pos.x << " y: " << pos.y << " z: " << pos.z;
304 }
305 else if (b)
306 {
307 b->resetPosition(pos, false);
309 reply << _L("Vehicle position set to: ") << "x: " << pos.x << " y: " << pos.y << " z: " << pos.z;
310 }
311 }
312
314 }
315};
316
317
318class AsCmd: public ConsoleCmd
319{
320public:
321 AsCmd(): ConsoleCmd("as", "<code>", _L("Run AngelScript code snippet")) {}
322
323 void Run(Ogre::StringVector const& args) override
324 {
325 if (!this->CheckAppState(AppState::SIMULATION))
326 return;
327
328 Str<200> reply;
329 reply << m_name << ": ";
330 Console::MessageType reply_type;
331
332#ifdef USE_ANGELSCRIPT
333 // we want to notify any running scripts that we might change something (prevent cheating)
335
336 // Re-compose the code snippet
337 Str<1000> code;
338 for (int i = 1; i < args.size(); ++i)
339 {
340 code << " " << args[i];
341 }
342
343 // Echo the code back to console user.
345 reply << " >>> " << code.ToCStr();
347
348 // Run the code - will output script messages/AngelScript errors.
350#else
352 reply << _L("Scripting disabled in this build");
354#endif
355 }
356};
357
359{
360public:
361 SpeedOfSoundCmd(): ConsoleCmd("speedofsound", "[]", _L("speedofsound - outputs the current speed of sound")) {}
362
363 void Run(Ogre::StringVector const& args) override
364 {
365 if (!this->CheckAppState(AppState::SIMULATION))
366 return;
367
368 Str<200> reply;
369 reply << m_name << ": ";
371
373 if (sound_manager == nullptr)
374 {
375 reply << _L("unable to get sound manager");
376 }
377 else
378 {
379 reply << _L("Current speed of sound: ") << sound_manager->GetSpeedOfSound();
380 }
381
383 }
384};
385
386class QuitCmd: public ConsoleCmd
387{
388public:
389 QuitCmd(): ConsoleCmd("quit", "[]", _L("quit - exit Rigs of Rods")) {}
390
391 void Run(Ogre::StringVector const& args) override
392 {
394 }
395};
396
397class HelpCmd: public ConsoleCmd
398{
399public:
400 HelpCmd(): ConsoleCmd("help", "[]", _L("help - information on commands (this)")) {}
401
402 void Run(Ogre::StringVector const& args) override
403 {
405 Console::CONSOLE_TITLE, _L("Available commands:"));
406
407 Str<500> line;
408 for (auto& cmd_pair: App::GetConsole()->getCommands())
409 {
410 line.Clear() << cmd_pair.second->getName() << " "
411 << cmd_pair.second->GetUsage() << " - " << cmd_pair.second->GetDoc();
412
415 }
416
418 Console::CONSOLE_TITLE, _L("Tips:"));
420 Console::CONSOLE_HELP, _L("- use Arrow Up/Down Keys in the InputBox to reuse old messages"));
421 }
422};
423
425{
426public:
427 LoadScriptCmd() : ConsoleCmd("loadscript", "[filename]", _L("Runs an AngelScript file")) {}
428
429 void Run(Ogre::StringVector const& args) override
430 {
431 Str<200> reply;
432 reply << m_name << ": ";
433 Console::MessageType reply_type;
434
435#ifdef USE_ANGELSCRIPT
436 if (args.size() == 1)
437 {
439 reply << _L("Missing parameter: ") << m_usage;
440 }
441 else
442 {
443 ScriptUnitID_t id = App::GetScriptEngine()->loadScript(args[1], ScriptCategory::CUSTOM);
444 if (id == SCRIPTUNITID_INVALID)
445 {
447 reply << _L("Failed to load script. See 'Angelscript.log' or use console command `log` and retry.");
448 }
449 else
450 {
452 reply << fmt::format(_L("Script '{}' running with ID '{}'"), args[1], id);
453 }
454 }
455#else
457 reply << _L("Scripting disabled in this build");
458#endif
459
461 }
462};
463
465{
466public:
467 LoadServerScriptCmd() : ConsoleCmd("loadserverscript", "[filename]", _L("Runs a RoRServer AngelScript file")) {}
468
469 void Run(Ogre::StringVector const& args) override
470 {
471 Str<200> reply;
472 reply << m_name << ": ";
473 Console::MessageType reply_type;
474
475#ifdef USE_ANGELSCRIPT
476 if (args.size() == 1)
477 {
479 reply << _L("Missing parameter: ") << m_usage;
480 }
481 else if (App::mp_state->getEnum<MpState>() == MpState::CONNECTED)
482 {
484 reply << _L("Not allowed while connected to network.");
485 }
486 else if (App::GetServerScript()->IsRunning())
487 {
489 reply << _L("Server script is already running.");
490 }
491 else
492 {
493 int result = App::GetServerScript()->Initialize(args[1]);
494 if (result != 0)
495 {
497 reply << _L("Failed to load server script. See 'RoRServerScript.log'.");
498 }
499 else
500 {
501 App::mp_state->setVal(MpState::LOCAL_SCRIPT);
502
503 // Construct user credentials
505 memset(&c, 0, sizeof(RoRnet::UserInfo));
508 strncpy(c.clientname, "LocalPlayer", 10);
509 std::string language = App::app_language->getStr().substr(0, 2);
510 std::string country = App::app_country->getStr().substr(0, 2);
511 strncpy(c.language, (language + std::string("_") + country).c_str(), 5);
512 strcpy(c.sessiontype, "normal");
513 c.authstatus = RoRnet::AUTH_ADMIN; // Register player as admin - serverscript engine assigns UID but doesn't do auth.
514 // Notify serverscript engine that player is added (assigns UID)
516 // Save user data locally to display in Player List UI.
518 // Refresh PlayerList UI to show local player.
520
522 reply << fmt::format(_L("Server script '{}' started"), args[1]);
523 }
524 }
525#else
527 reply << _L("Scripting disabled in this build");
528#endif
529
531 }
532};
533
535{
536public:
537 UnloadServerScriptCmd() : ConsoleCmd("unloadserverscript", "", _L("Stops a running RoRServer script")) {}
538
539 void Run(Ogre::StringVector const& args) override
540 {
541 Str<200> reply;
542 reply << m_name << ": ";
543 Console::MessageType reply_type;
544
545#ifdef USE_ANGELSCRIPT
546 if (!App::GetServerScript()->IsRunning())
547 {
549 reply << _L("Server script was not running.");
550 }
551 else
552 {
554 App::mp_state->setVal(MpState::DISABLED);
556 reply << _L("Server script stopped.");
557 }
558#else
560 reply << _L("Scripting disabled in this build");
561#endif
562
564 }
565};
566
567// -------------------------------------------------------------------------------------
568// CVar (builtin) console commmands
569
570class VarsCmd: public ConsoleCmd
571{
572public:
573 VarsCmd(): ConsoleCmd("vars", "[<expr> ...]", _L("Print cvars with one of <expr> in name")) {}
574
575 void Run(Ogre::StringVector const& args) override
576 {
577 for (auto& pair: App::GetConsole()->getCVars())
578 {
579 bool match = args.size() == 1;
580 for (size_t i = 1; i < args.size(); ++i)
581 {
582 if (pair.first.find(args[i]) != std::string::npos)
583 {
584 match = true;
585 break;
586 }
587 }
588
589 if (match)
590 {
591 Str<200> reply;
592 reply << "vars: " << pair.first << "=" << pair.second->getStr() << " (";
593
594 if (pair.second->hasFlag(CVAR_TYPE_BOOL)) { reply << "bool"; }
595 else if (pair.second->hasFlag(CVAR_TYPE_INT)) { reply << "int"; }
596 else if (pair.second->hasFlag(CVAR_TYPE_FLOAT)) { reply << "float"; }
597 else { reply << "string"; }
598
599 if (pair.second->hasFlag(CVAR_ARCHIVE)) { reply << ", archive"; }
600 if (pair.second->hasFlag(CVAR_NO_LOG)) { reply << ", no log"; }
601
602 reply << ")";
604 }
605 }
606 }
607};
608
609class SetCmd: public ConsoleCmd
610{
611public:
612 SetCmd(): ConsoleCmd("set", "<cvar> [<flags>] [<value>]", _L("Get or set value of existing CVar")) {}
613
614 void Run(Ogre::StringVector const& args) override
615 {
616 Str<200> reply;
617 reply << m_name << ": ";
619
620 if (args.size() == 1)
621 {
622 reply_type = Console::CONSOLE_HELP;
623 reply << this->GetUsage() << " - " << this->GetDoc();
624 }
625 else
626 {
627 CVar* cvar = App::GetConsole()->cVarFind(args[1]);
628 if (cvar)
629 {
630 if (args.size() > 2)
631 {
632 App::GetConsole()->cVarAssign(cvar, args[2]);
633 }
635 reply << cvar->getName() << " = " << cvar->getStr();
636 }
637 else
638 {
640 reply << _L("No such CVar: ") << args[1];
641 }
642 }
643
645 }
646};
647
648class SetCVarCmd: public ConsoleCmd // Generic
649{
650public:
651 SetCVarCmd(std::string const& name, std::string const& usage, std::string const& doc, int flag):
652 ConsoleCmd(name, usage, doc), m_cvar_flag(flag)
653 {}
654
655 void Run(Ogre::StringVector const& args) override
656 {
657 Str<200> reply;
658 reply << m_name << ": ";
659 Console::MessageType reply_type;
660
661 if (args.size() == 1)
662 {
663 reply_type = Console::CONSOLE_HELP;
664 reply << this->GetUsage() << " - " << this->GetDoc() << "Switches: --autoapply/--allowstore/--autostore";
665 }
666 else
667 {
668 int flags = m_cvar_flag;
669 size_t i;
670 for (i = 1; i < args.size(); ++i)
671 {
672 if (args[i] == "--archive") { flags |= CVAR_ARCHIVE; }
673 else break; // Exit loop on first non-switch arg!
674 }
675
676 if (i == args.size()) // Only switches but no cvar?
677 {
678 reply_type = Console::CONSOLE_HELP;
679 reply << this->GetUsage() << " - " << this->GetDoc() << "Switches: --archive";
680 }
681 else
682 {
683 CVar* cvar = App::GetConsole()->cVarGet(args[i], flags);
684 if (args.size() > (i+1))
685 {
686 App::GetConsole()->cVarAssign(cvar, args[i+1]);
687 }
689 reply << cvar->getName() << " = " << cvar->getStr();
690 }
691 }
692
694 }
695private:
697};
698
700{
701public:
702 SetstringCmd(): SetCVarCmd("setstring", "<cvar> [<value>]", _L("Set or create string CVar"), /*flag=*/0) {}
703};
704
706{
707public:
708 SetboolCmd(): SetCVarCmd("setbool", "<cvar> [<value>]", _L("Set or create boolean CVar"), CVAR_TYPE_BOOL) {}
709};
710
712{
713public:
714 SetintCmd(): SetCVarCmd("setint", "<cvar> [<value>]", _L("Set or create integer CVar"), CVAR_TYPE_INT) {}
715};
716
718{
719public:
720 SetfloatCmd(): SetCVarCmd("setfloat", "<cvar> [<value>]", _L("Set or create real-number CVar"), CVAR_TYPE_FLOAT) {}
721};
722
723class ClearCmd: public ConsoleCmd
724{
725public:
726 ClearCmd(): ConsoleCmd("clear", "[<type>]", _L("Clear console history. Types: all/info/net/chat/terrn/actor/script")) {}
727
728 void Run(Ogre::StringVector const& args) override
729 {
730 if (args.size() < 2 || args[1] == "all")
731 {
733 lock.messages.clear();
734 }
735 else
736 {
737 // Create a predicate function
738 std::function<bool(Console::Message const& m)> filter_fn;
739 if (args[1] == "chat")
740 {
741 filter_fn = [](Console::Message const& m){ return m.cm_type == Console::CONSOLE_SYSTEM_NETCHAT; };
742 }
743 else if (args[1] == "net") // Chat and user notifications
744 {
745 filter_fn = [](Console::Message const& m){ return m.cm_net_userid != 0; };
746 }
747 else
748 {
750 bool valid = false;
751 if (args[1] == "info") { area = Console::CONSOLE_MSGTYPE_INFO; valid = true; }
752 else if (args[1] == "terrn") { area = Console::CONSOLE_MSGTYPE_TERRN; valid = true; }
753 else if (args[1] == "actor") { area = Console::CONSOLE_MSGTYPE_ACTOR; valid = true; }
754 else if (args[1] == "script") { area = Console::CONSOLE_MSGTYPE_SCRIPT; valid = true; }
755
756 if (valid)
757 {
758 filter_fn = [area](Console::Message const& m) { return m.cm_area == area; };
759 }
760 else
761 {
763 fmt::format(_L("No such message type: {}"), args[1]));
764 }
765 }
766
768 // Shove unwanted entries to the end
769 auto erase_begin = std::remove_if(lock.messages.begin(), lock.messages.end(), filter_fn);
770 // Erase unwanted
771 lock.messages.erase(erase_begin, lock.messages.end());
772 }
773 }
774};
775
777
778// -------------------------------------------------------------------------------------
779// Console integration
780
782{
783 ConsoleCmd* cmd = nullptr;
784
785 // Classics
786 cmd = new GravityCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
787 cmd = new WaterlevelCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
788 cmd = new TerrainheightCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
789 cmd = new SpawnobjectCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
790 cmd = new LogCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
791 cmd = new VerCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
792 cmd = new PosCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
793 cmd = new GotoCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
794 cmd = new AsCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
795 cmd = new QuitCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
796 cmd = new HelpCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
797 // Additions
798 cmd = new ClearCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
799 cmd = new LoadScriptCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
800 cmd = new LoadServerScriptCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
801 cmd = new UnloadServerScriptCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
802 cmd = new SpeedOfSoundCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
803 // CVars
804 cmd = new SetCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
805 cmd = new SetstringCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
806 cmd = new SetboolCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
807 cmd = new SetintCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
808 cmd = new SetfloatCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
809 cmd = new VarsCmd(); m_commands.insert(std::make_pair(cmd->getName(), cmd));
810}
811
812void Console::doCommand(std::string msg)
813{
814 if (msg[0] == '/' || msg[0] == '\\')
815 {
817 _L("Using slashes before commands are deprecated, you can now type command without any slashes"));
818 msg.erase(msg.begin());
819 }
820
821 if (msg[0] == '!')
822 {
823 // Server commands - pass through to multiplayer chat
824 App::GetNetwork()->BroadcastChatMsg(msg.c_str());
825 return;
826 }
827
828 Ogre::StringVector args = Ogre::StringUtil::split(msg, " ");
829
830 auto found = m_commands.find(args[0]);
831 if (found != m_commands.end())
832 {
833 found->second->Run(args);
834 return;
835 }
836
837 CVar* cvar = this->cVarFind(args[0]);
838 if (cvar)
839 {
840 Str<200> reply;
841 reply << cvar->getName() << " = " << cvar->getStr();
843 return;
844 }
845
846 Str<200> reply;
847 reply << _L("unknown command: ") << msg;
849}
850
851// -------------------------------------------------------------------------------------
852// Helpers
853
855{
856 if (App::app_state->getEnum<AppState>() == state)
857 return true;
858
859 Str<200> reply;
860 reply << m_name << ": ";
861 if (state == AppState::SIMULATION)
862 {
863 reply << _L("Only allowed when simulation is running");
864 }
865 else
866 {
867 reply << _L("Not allowed in current app state");
868 }
870 return false;
871}
872
873 // Currently unused: _L("Please enter a correct value. ")
874
Central state/object manager and communications hub.
#define ROR_ASSERT(_EXPR)
Definition Application.h:40
#define PARSEREAL(x)
Definition Application.h:60
#define _L
Game state manager and message-queue provider.
#define strnlen(str, len)
const char *const ROR_BUILD_DATE
const char *const ROR_VERSION_STRING
const char *const ROR_BUILD_TIME
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
Ogre::Vector3 getPosition()
Definition Actor.cpp:370
ActorInstanceID_t ar_instance_id
Static attr; session-unique ID.
Definition Actor.h:464
void resetPosition(Ogre::Vector3 translation, bool setInitPosition)
Moves the actor to given world coords (pivot point is node 0).
Definition Actor.cpp:1351
Quake-style console variable, defined in RoR.cfg or crated via Console UI and scripts.
Definition CVar.h:53
std::string const & getName() const
Definition CVar.h:103
std::string const & getStr() const
Definition CVar.h:95
bool getBool() const
Definition CVar.h:98
void setVal(T val)
Definition CVar.h:72
void setPosition(Ogre::Vector3 position)
Definition Character.cpp:85
Ogre::Vector3 getPosition()
Definition Character.cpp:92
Base (abstract) console command.
Definition ConsoleCmd.h:38
std::string const & GetDoc() const
Definition ConsoleCmd.h:49
std::string const & GetUsage() const
Definition ConsoleCmd.h:48
std::string const & getName() const
Definition ConsoleCmd.h:47
std::string m_name
Definition ConsoleCmd.h:54
std::string m_usage
Definition ConsoleCmd.h:55
void cVarAssign(CVar *cvar, std::string const &value)
Parse value by cvar type.
Definition CVar.cpp:258
CommandPtrMap & getCommands()
Definition Console.h:134
CommandPtrMap m_commands
Definition Console.h:162
@ CONSOLE_MSGTYPE_ACTOR
Parsing/spawn/simulation messages for actors.
Definition Console.h:63
@ CONSOLE_MSGTYPE_SCRIPT
Messages sent from scripts.
Definition Console.h:62
@ CONSOLE_MSGTYPE_INFO
Generic message.
Definition Console.h:60
@ CONSOLE_MSGTYPE_TERRN
Parsing/spawn/simulation messages for terrain.
Definition Console.h:64
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition Console.cpp:103
CVar * cVarFind(std::string const &input_name)
Find cvar by short/long name.
Definition CVar.cpp:276
@ CONSOLE_SYSTEM_ERROR
Definition Console.h:52
@ CONSOLE_SYSTEM_REPLY
Success.
Definition Console.h:54
@ CONSOLE_SYSTEM_NETCHAT
Definition Console.h:55
@ CONSOLE_TITLE
Definition Console.h:49
CVar * cVarGet(std::string const &input_name, int flags)
Get cvar by short/long name, or create new one using input as short name.
Definition CVar.cpp:304
CVarPtrMap & getCVars()
Definition Console.h:132
Character * GetPlayerCharacter()
const ActorPtr & GetPlayerActor()
const TerrainPtr & GetTerrain()
void PushMessage(Message m)
Doesn't guarantee order! Use ChainMessage() if order matters.
void SetLocalUserData(RoRnet::UserInfo const &user)
Definition Network.cpp:892
void BroadcastChatMsg(const char *msg)
Definition Network.cpp:839
ScriptUnitID_t loadScript(Ogre::String filename, ScriptCategory category=ScriptCategory::TERRAIN, ActorPtr associatedActor=nullptr, int32_t associatedNetUid=-1, std::string buffer="")
Loads a script.
ScriptRetCode_t executeString(Ogre::String command)
executes a string (useful for the console)
void triggerEvent(scriptEvents eventnum, int arg1=0, int arg2ex=0, int arg3ex=0, int arg4ex=0, std::string arg5ex="", std::string arg6ex="", std::string arg7ex="", std::string arg8ex="")
triggers an event; Not to be used by the end-user.
int Initialize(const std::string &script_filename)
void createClient(RoRnet::UserInfo &user)
float GetSpeedOfSound() const
SoundManager * getSoundManager()
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
Definition Str.h:36
const char * ToCStr() const
Definition Str.h:46
Str & Clear()
Definition Str.h:54
void setGravity(float value)
Definition Terrain.cpp:489
float getWaterHeight() const
Definition Terrain.cpp:597
float getHeightAt(float x, float z)
Definition Terrain.cpp:511
Wavefield * getWater()
Definition Terrain.h:87
float getGravity() const
Definition Terrain.h:101
float GetStaticWaterHeight()
Returns static water level configured in 'terrn2'.
Definition Wavefield.cpp:75
void Run(Ogre::StringVector const &args) override
SetCVarCmd(std::string const &name, std::string const &usage, std::string const &doc, int flag)
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void Run(Ogre::StringVector const &args) override
void regBuiltinCommands()
Register builtin commands.
void doCommand(std::string msg)
Identify and execute any console line.
bool CheckAppState(AppState state)
@ CVAR_ARCHIVE
Will be written to RoR.cfg.
Definition CVar.h:41
@ CVAR_TYPE_INT
Definition CVar.h:39
@ CVAR_NO_LOG
Will not be written to RoR.log.
Definition CVar.h:42
@ CVAR_TYPE_FLOAT
Definition CVar.h:40
@ CVAR_TYPE_BOOL
Definition CVar.h:38
@ MSG_GUI_MP_CLIENTS_REFRESH
@ MSG_APP_SHUTDOWN_REQUESTED
Definition Application.h:87
static const float DEFAULT_GRAVITY
earth gravity
void TRIGGER_EVENT_ASYNC(scriptEvents type, int arg1, int arg2ex=0, int arg3ex=0, int arg4ex=0, std::string arg5ex="", std::string arg6ex="", std::string arg7ex="", std::string arg8ex="")
Asynchronously (via MSG_SIM_SCRIPT_EVENT_TRIGGERED) invoke script function eventCallbackEx(),...
CVar * mp_player_name
ServerScriptSequencer * GetServerScript()
CVar * app_language
CVar * app_country
SoundScriptManager * GetSoundScriptManager()
GameContext * GetGameContext()
CVar * app_state
CVar * mp_state
Console * GetConsole()
ScriptEngine * GetScriptEngine()
Network * GetNetwork()
CVar * diag_log_console_echo
@ ASMANIP_CONSOLE_SNIPPET_EXECUTED
int ScriptUnitID_t
Unique sequentially generated ID of a loaded and running scriptin session. Use ScriptEngine::getScrip...
static const ScriptUnitID_t SCRIPTUNITID_INVALID
@ SE_ANGELSCRIPT_MANIPULATIONS
triggered when the user tries to dynamically use the scripting capabilities (prevent cheating) args: ...
@ SE_TRUCK_TELEPORT
triggered when the user teleports the truck, the argument refers to the actor ID of the vehicle
@ AUTH_ADMIN
admin on the server
Definition RoRnet.h:78
#define RORNET_VERSION
Definition RoRnet.h:35
#define RORNET_MAX_USERNAME_LEN
bytes.
Definition RoRnet.h:33
MessageType cm_type
Definition Console.h:75
uint32_t cm_net_userid
Definition Console.h:77
MessageArea cm_area
Definition Console.h:74
std::vector< Message > & messages
Definition Console.h:91
Unified game event system - all requests and state changes are reported using a message.
Definition GameContext.h:52
int32_t authstatus
auth status set by server: AUTH_*
Definition RoRnet.h:192
char clientname[10]
the name and version of the client. For exmaple: "ror" or "gamebot"
Definition RoRnet.h:200
char language[10]
user's language. For example "de-DE" or "en-US"
Definition RoRnet.h:199
char username[RORNET_MAX_USERNAME_LEN]
the nickname of the user (UTF-8)
Definition RoRnet.h:196
char sessiontype[10]
the requested session type. For example "normal", "bot", "rcon"
Definition RoRnet.h:203
char clientversion[25]
a version number of the client. For example 1 for RoR 0.35
Definition RoRnet.h:201