77#include " api/EntityAPI.h"
88#include " api/ItemAPI.h"
99#include " api/McAPI.h"
10- #include " api/PlayerAPI.h"
1110#include " engine/EngineOwnData.h"
1211#include " engine/GlobalShareData.h"
1312#include " engine/LocalShareData.h"
4746#include < vector>
4847
4948using namespace ll ::command;
49+ using ll::event::EventBus;
50+ using ll::event::ServerStartedEvent;
5051
5152// ////////////////// Class Definition ////////////////////
5253
@@ -260,9 +261,20 @@ Local<Value> McClass::newCommand(const Arguments& args) {
260261 }
261262 }
262263 }
263- auto & command = CommandRegistrar::getInstance ().getOrCreateCommand (name, desc, permission, flag);
264- if (!alias.empty ()) {
265- command.alias (alias);
264+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
265+ EventBus::getInstance ().emplaceListener <ServerStartedEvent>(
266+ [name, desc, permission, flag, alias](ServerStartedEvent&) {
267+ auto & command = CommandRegistrar::getInstance ().getOrCreateCommand (name, desc, permission, flag);
268+ if (!alias.empty ()) {
269+ command.alias (alias);
270+ }
271+ }
272+ );
273+ } else {
274+ auto & command = CommandRegistrar::getInstance ().getOrCreateCommand (name, desc, permission, flag);
275+ if (!alias.empty ()) {
276+ command.alias (alias);
277+ }
266278 }
267279 return CommandClass::newCommand (name);
268280 }
@@ -291,7 +303,16 @@ Local<Value> CommandClass::setAlias(const Arguments& args) {
291303 CHECK_ARGS_COUNT (args, 1 )
292304 CHECK_ARG_TYPE (args[0 ], ValueKind::kString )
293305 try {
294- get ().alias (args[0 ].asString ().toString ());
306+ std::string alias = args[0 ].asString ().toString ();
307+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
308+ EventBus::getInstance ().emplaceListener <ServerStartedEvent>([commandName (commandName),
309+ alias](ServerStartedEvent&) {
310+ ll::command::CommandRegistrar::getInstance ().getOrCreateCommand (commandName).alias (alias);
311+ });
312+ return Boolean::newBoolean (true );
313+ } else {
314+ get ().alias (alias);
315+ }
295316 return Boolean::newBoolean (true );
296317 }
297318 CATCH (" Fail in setAlias!" )
@@ -310,8 +331,15 @@ Local<Value> CommandClass::setEnum(const Arguments& args) {
310331 for (int i = 0 ; i < enumArr.size (); ++i) {
311332 enumValues.push_back ({enumArr.get (i).asString ().toString (), i});
312333 }
313- if (CommandRegistrar::getInstance ().tryRegisterRuntimeEnum (enumName, std::move (enumValues))) {
334+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
335+ EventBus::getInstance ().emplaceListener <ServerStartedEvent>([enumName, enumValues](ServerStartedEvent&) {
336+ CommandRegistrar::getInstance ().tryRegisterRuntimeEnum (enumName, std::move (enumValues));
337+ });
314338 return String::newString (enumName);
339+ } else {
340+ if (CommandRegistrar::getInstance ().tryRegisterRuntimeEnum (enumName, std::move (enumValues))) {
341+ return String::newString (enumName);
342+ }
315343 }
316344 return {};
317345 }
@@ -443,7 +471,6 @@ Local<Value> CommandClass::optional(const Arguments& args) {
443471Local<Value> CommandClass::addOverload (const Arguments& args) {
444472 try {
445473 if (args.size () == 0 ) return Boolean::newBoolean (true );
446- auto cmd = get ().runtimeOverload (getEngineOwnData ()->plugin );
447474 auto overloadFunc = [](RuntimeOverload& cmd, std::string const & commandName, std::string const & paramName) {
448475 auto & paramList = getEngineOwnData ()->plugin ->registeredCommands [commandName];
449476 for (auto & info : paramList) {
@@ -464,40 +491,128 @@ Local<Value> CommandClass::addOverload(const Arguments& args) {
464491 }
465492 }
466493 };
494+ auto delayRegFunc = [this , &overloadFunc](std::vector<std::string>& enumValues) {
495+ EventBus::getInstance ().emplaceListener <ServerStartedEvent>([enumValues,
496+ commandName (commandName),
497+ overloadFunc,
498+ e (EngineScope::currentEngine ()
499+ )](ServerStartedEvent&) {
500+ auto cmd = ll::command::CommandRegistrar::getInstance ()
501+ .getOrCreateCommand (commandName)
502+ .runtimeOverload (getEngineData (e)->plugin );
503+ for (auto & paramName : enumValues) {
504+ auto & paramList = getEngineData (e)->plugin ->registeredCommands [commandName];
505+ for (auto & info : paramList) {
506+ if (info.name == paramName || info.enumName == paramName) {
507+ if (info.optional ) {
508+ if (info.type == ParamKind::Kind::Enum || info.type == ParamKind::Kind::SoftEnum) {
509+ cmd.optional (info.enumName , info.type , info.enumName ).option (info.option );
510+ } else {
511+ cmd.optional (info.name , info.type ).option (info.option );
512+ }
513+ } else {
514+ if (info.type == ParamKind::Kind::Enum || info.type == ParamKind::Kind::SoftEnum) {
515+ cmd.required (info.enumName , info.type , info.enumName ).option (info.option );
516+ } else {
517+ cmd.required (info.name , info.type ).option (info.option );
518+ }
519+ }
520+ }
521+ }
522+ }
523+ cmd.execute (onExecute);
524+ });
525+ };
526+
467527 if (args[0 ].isNumber ()) {
468- for (int i = 0 ; i < args.size (); ++i) {
469- CHECK_ARG_TYPE (args[i], ValueKind::kNumber );
470- std::string paramName = std::to_string (args[i].asNumber ().toInt32 ());
471- overloadFunc (cmd, commandName, paramName);
528+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
529+ std::vector<std::string> enumValues;
530+ for (int i = 0 ; i < args.size (); ++i) {
531+ CHECK_ARG_TYPE (args[i], ValueKind::kNumber );
532+ enumValues.push_back (std::to_string (args[i].asNumber ().toInt32 ()));
533+ }
534+ delayRegFunc (enumValues);
535+ } else {
536+ auto cmd = get ().runtimeOverload (getEngineOwnData ()->plugin );
537+ for (int i = 0 ; i < args.size (); ++i) {
538+ CHECK_ARG_TYPE (args[i], ValueKind::kNumber );
539+ std::string paramName = std::to_string (args[i].asNumber ().toInt32 ());
540+ overloadFunc (cmd, commandName, paramName);
541+ }
542+ cmd.execute (onExecute);
472543 }
473- cmd.execute (onExecute);
474544 return Boolean::newBoolean (true );
475545 } else if (args[0 ].isString ()) {
476- for (int i = 0 ; i < args.size (); ++i) {
477- CHECK_ARG_TYPE (args[i], ValueKind::kString );
478- std::string paramName = args[0 ].asString ().toString ();
479- overloadFunc (cmd, commandName, paramName);
546+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
547+ std::vector<std::string> enumValues;
548+ for (int i = 0 ; i < args.size (); ++i) {
549+ CHECK_ARG_TYPE (args[i], ValueKind::kString );
550+ enumValues.push_back (args[0 ].asString ().toString ());
551+ }
552+ delayRegFunc (enumValues);
553+ } else {
554+ auto cmd = get ().runtimeOverload (getEngineOwnData ()->plugin );
555+ for (int i = 0 ; i < args.size (); ++i) {
556+ CHECK_ARG_TYPE (args[i], ValueKind::kString );
557+ std::string paramName = args[0 ].asString ().toString ();
558+ overloadFunc (cmd, commandName, paramName);
559+ }
560+ cmd.execute (onExecute);
480561 }
481- cmd.execute (onExecute);
482562 return Boolean::newBoolean (true );
483563 } else if (args[0 ].isArray ()) {
484564 auto arr = args[0 ].asArray ();
485- if (arr.size () == 0 ) return Boolean::newBoolean (true );
565+ if (arr.size () == 0 ) {
566+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
567+ EventBus::getInstance ().emplaceListener <ServerStartedEvent>(
568+ [commandName (commandName), e (EngineScope::currentEngine ())](ServerStartedEvent&) {
569+ auto cmd = ll::command::CommandRegistrar::getInstance ()
570+ .getOrCreateCommand (commandName)
571+ .runtimeOverload (getEngineData (e)->plugin );
572+ cmd.execute (onExecute);
573+ }
574+ );
575+ } else {
576+ auto cmd = get ().runtimeOverload (getEngineOwnData ()->plugin );
577+ cmd.execute (onExecute);
578+ }
579+ return Boolean::newBoolean (true );
580+ }
486581 if (arr.get (0 ).isNumber ()) {
487- for (int i = 0 ; i < arr.size (); ++i) {
488- CHECK_ARG_TYPE (arr.get (i), ValueKind::kNumber );
489- std::string paramName = std::to_string (arr.get (i).asNumber ().toInt32 ());
490- overloadFunc (cmd, commandName, paramName);
582+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
583+ std::vector<std::string> enumValues;
584+ for (int i = 0 ; i < arr.size (); ++i) {
585+ CHECK_ARG_TYPE (arr.get (i), ValueKind::kNumber );
586+ enumValues.push_back (std::to_string (arr.get (i).asNumber ().toInt32 ()));
587+ }
588+ delayRegFunc (enumValues);
589+ } else {
590+ auto cmd = get ().runtimeOverload (getEngineOwnData ()->plugin );
591+ for (int i = 0 ; i < arr.size (); ++i) {
592+ CHECK_ARG_TYPE (arr.get (i), ValueKind::kNumber );
593+ std::string paramName = std::to_string (arr.get (i).asNumber ().toInt32 ());
594+ overloadFunc (cmd, commandName, paramName);
595+ }
596+ cmd.execute (onExecute);
491597 }
492- cmd.execute (onExecute);
493598 return Boolean::newBoolean (true );
494599 } else if (arr.get (0 ).isString ()) {
495- for (int i = 0 ; i < arr.size (); ++i) {
496- CHECK_ARG_TYPE (arr.get (i), ValueKind::kString );
497- std::string paramName = arr.get (i).asString ().toString ();
498- overloadFunc (cmd, commandName, paramName);
600+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
601+ std::vector<std::string> enumValues;
602+ for (int i = 0 ; i < arr.size (); ++i) {
603+ CHECK_ARG_TYPE (arr.get (i), ValueKind::kString );
604+ enumValues.push_back (arr.get (i).asString ().toString ());
605+ }
606+ delayRegFunc (enumValues);
607+ } else {
608+ auto cmd = get ().runtimeOverload (getEngineOwnData ()->plugin );
609+ for (int i = 0 ; i < arr.size (); ++i) {
610+ CHECK_ARG_TYPE (arr.get (i), ValueKind::kString );
611+ std::string paramName = arr.get (i).asString ().toString ();
612+ overloadFunc (cmd, commandName, paramName);
613+ }
614+ cmd.execute (onExecute);
499615 }
500- cmd.execute (onExecute);
501616 return Boolean::newBoolean (true );
502617 }
503618 }
@@ -512,8 +627,7 @@ Local<Value> CommandClass::setCallback(const Arguments& args) {
512627 CHECK_ARGS_COUNT (args, 1 );
513628 CHECK_ARG_TYPE (args[0 ], ValueKind::kFunction );
514629 try {
515- auto func = args[0 ].asFunction ();
516- auto & command = get ();
630+ auto func = args[0 ].asFunction ();
517631 localShareData
518632 ->commandCallbacks [commandName] = {EngineScope::currentEngine (), 0 , script::Global<Function>(func)};
519633 return Boolean::newBoolean (true );
@@ -548,7 +662,13 @@ Local<Value> CommandClass::setSoftEnum(const Arguments& args) {
548662 try {
549663 auto name = args[0 ].asString ().toString ();
550664 auto enums = parseStringList (args[1 ].asArray ());
551- CommandRegistrar::getInstance ().tryRegisterSoftEnum (name, std::move (enums));
665+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
666+ EventBus::getInstance ().emplaceListener <ServerStartedEvent>([name, enums](ServerStartedEvent&) {
667+ CommandRegistrar::getInstance ().tryRegisterSoftEnum (name, std::move (enums));
668+ });
669+ } else {
670+ CommandRegistrar::getInstance ().tryRegisterSoftEnum (name, std::move (enums));
671+ }
552672 return Boolean::newBoolean (true );
553673 }
554674 CATCH (" Fail in setSoftEnum!" );
@@ -561,7 +681,13 @@ Local<Value> CommandClass::addSoftEnumValues(const Arguments& args) {
561681 try {
562682 auto name = args[0 ].asString ().toString ();
563683 auto enums = parseStringList (args[1 ].asArray ());
564- CommandRegistrar::getInstance ().addSoftEnumValues (name, std::move (enums));
684+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
685+ EventBus::getInstance ().emplaceListener <ServerStartedEvent>([name, enums](ServerStartedEvent&) {
686+ CommandRegistrar::getInstance ().addSoftEnumValues (name, std::move (enums));
687+ });
688+ } else {
689+ CommandRegistrar::getInstance ().addSoftEnumValues (name, std::move (enums));
690+ }
565691 return Boolean::newBoolean (true );
566692 }
567693 CATCH (" Fail in addSoftEnumValues!" );
@@ -574,7 +700,13 @@ Local<Value> CommandClass::removeSoftEnumValues(const Arguments& args) {
574700 try {
575701 auto name = args[0 ].asString ().toString ();
576702 auto enums = parseStringList (args[1 ].asArray ());
577- CommandRegistrar::getInstance ().removeSoftEnumValues (name, std::move (enums));
703+ if (ll::getGamingStatus () == ll::GamingStatus::Starting) {
704+ EventBus::getInstance ().emplaceListener <ServerStartedEvent>([name, enums](ServerStartedEvent&) {
705+ CommandRegistrar::getInstance ().removeSoftEnumValues (name, std::move (enums));
706+ });
707+ } else {
708+ CommandRegistrar::getInstance ().removeSoftEnumValues (name, std::move (enums));
709+ }
578710 return Boolean::newBoolean (true );
579711 }
580712 CATCH (" Fail in removeSoftEnumValues!" );
@@ -584,11 +716,14 @@ Local<Value> CommandClass::getSoftEnumValues(const Arguments& args) {
584716 CHECK_ARGS_COUNT (args, 1 );
585717 CHECK_ARG_TYPE (args[0 ], ValueKind::kString );
586718 try {
587- auto name = args[0 ].asString ().toString ();
588- auto & lookup = ll::service::getCommandRegistry ()->mSoftEnumLookup ;
589- auto & softEnums = ll::service::getCommandRegistry ()->mSoftEnums ;
590- if (lookup.find (name) != lookup.end ()) {
591- return getStringArray (softEnums[lookup[name]].mValues );
719+ auto name = args[0 ].asString ().toString ();
720+ auto registry = ll::service::getCommandRegistry ();
721+ if (registry) {
722+ auto & lookup = registry->mSoftEnumLookup ;
723+ auto & softEnums = registry->mSoftEnums ;
724+ if (lookup.find (name) != lookup.end ()) {
725+ return getStringArray (softEnums[lookup[name]].mValues );
726+ }
592727 }
593728 return {};
594729 }
@@ -597,7 +732,9 @@ Local<Value> CommandClass::getSoftEnumValues(const Arguments& args) {
597732
598733Local<Value> CommandClass::getSoftEnumNames (const Arguments&) {
599734 try {
600- auto & lookup = ll::service::getCommandRegistry ()->mSoftEnums ;
735+ auto registry = ll::service::getCommandRegistry ();
736+ if (!registry) return {};
737+ auto & lookup = registry->mSoftEnums ;
601738 std::vector<std::string> names;
602739 for (auto & [name, _] : lookup) {
603740 names.push_back (name);
0 commit comments