Skip to content

Commit 57883da

Browse files
committed
feat: support command delay registry
1 parent a08cf76 commit 57883da

File tree

1 file changed

+176
-39
lines changed

1 file changed

+176
-39
lines changed

src/legacy/api/CommandAPI.cpp

Lines changed: 176 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
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"
@@ -47,6 +46,8 @@
4746
#include <vector>
4847

4948
using 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) {
443471
Local<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

598733
Local<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

Comments
 (0)