/**
* Command for managing features.
* Copyright 2022 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
* Acedia is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License, or
* (at your option) any later version.
*
* Acedia is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see .
*/
class ACommandFeature extends Command;
// TODO: autoconf, newconf, deleteconf, setconf
// TODO: when displaying features - display which one is enabled
protected function BuildData(CommandDataBuilder builder)
{
builder.Name(P("feature")).Summary(P("Managing features."))
.Describe(P("Command for displaying and enabling/disabling features."));
builder.SubCommand(P("enable"))
.ParamText(P("feature"))
.OptionalParams()
.ParamText(P("config"))
.Describe(P("Enables specified ."));
builder.SubCommand(P("disable"))
.ParamText(P("feature"))
.Describe(P("Disables specified ."));
}
protected function Executed(CallData result, EPlayer callerPlayer)
{
if (result.subCommandName.IsEmpty()) {
ShowAllFeatures();
}
else if (result.subCommandName.Compare(P("enable")))
{
TryEnableFeature(
callerPlayer,
result.parameters.GetText(P("feature")),
result.parameters.GetText(P("config")));
}
else if (result.subCommandName.Compare(P("disable"))) {
DisableFeature(callerPlayer, result.parameters.GetText(P("feature")));
}
}
protected function TryEnableFeature(
EPlayer callerPlayer,
Text featureName,
Text chosenConfig)
{
local Text oldConfig, newConfig;
local class featureClass;
local class configClass;
featureClass = LoadFeatureClass(featureName);
if (featureClass == none) return;
configClass = featureClass.default.configClass;
if (configClass == none) return;
if (chosenConfig == none) {
newConfig = configClass.static.GetAutoEnabledConfig();
}
else if (!configClass.static.Exists(chosenConfig))
{
callerConsole
.Write(P("Specified config \""))
.Write(chosenConfig)
.WriteLine(F("\" {$TextFailure doesn't exist}"));
return;
}
else {
newConfig = chosenConfig.Copy();
}
if (newConfig == none)
{
callerConsole
.Write(F("{$TextFailue No config specified} and"
@ "{$TextFailure no auto-enabled config} exists for feature "))
.UseColorOnce(_.color.TextEmphasis)
.WriteLine(newConfig);
_.memory.Free(newConfig);
return;
}
oldConfig = featureClass.static.GetCurrentConfig();
if (oldConfig != none && oldConfig.Compare(chosenConfig, SCASE_INSENSITIVE))
{
callerConsole
.Write(P("Config "))
.Write(chosenConfig)
.WriteLine(P(" is already enabled"));
_.memory.Free(oldConfig);
_.memory.Free(newConfig);
return;
}
EnableFeature(
callerPlayer,
featureClass,
configClass,
newConfig,
chosenConfig == none);
_.memory.Free(newConfig);
_.memory.Free(oldConfig);
}
protected function EnableFeature(
EPlayer callerPlayer,
class featureClass,
class configClass,
Text chosenConfig,
bool autoConfig)
{
local bool wasEnabled;
local Feature instance;
local Text featureName, callerName;
if (callerPlayer == none) return;
if (featureClass == none) return;
if (configClass == none) return;
callerName = callerPlayer.GetName();
featureName = _.text.FromClass(featureClass);
wasEnabled = featureClass.static.IsEnabled();
instance = featureClass.static.EnableMe(chosenConfig);
if (instance == none)
{
callerConsole.Write(F("Something went {$TextFailure wrong},"
@ "{$TextFailure failed} to enabled feature"))
.UseColorOnce(_.color.TextEmphasis).WriteLine(featureName);
}
else if (wasEnabled)
{
callerConsole
.Write(P("Swapping config for the feature "))
.UseColorOnce(_.color.TextEmphasis).Write(featureName)
.Write(P(" to \"")).Write(chosenConfig).WriteLine(P("\""));
othersConsole
.Write(callerName)
.Write(P(" swapped config for the feature "))
.UseColorOnce(_.color.TextEmphasis).Write(featureName)
.Write(P(" to \"")).Write(chosenConfig).WriteLine(P("\""));
}
else
{
callerConsole
.Write(P("Enabling feature "))
.UseColorOnce(_.color.TextEmphasis).Write(featureName)
.Write(P(" with config \"")).Write(chosenConfig).WriteLine(P("\""));
othersConsole
.Write(callerName)
.Write(P(" enabled feature "))
.UseColorOnce(_.color.TextEmphasis).Write(featureName)
.Write(P(" with config \"")).Write(chosenConfig).WriteLine(P("\""));
}
_.memory.Free(callerName);
_.memory.Free(featureName);
}
protected function DisableFeature(EPlayer callerPlayer, Text featureName)
{
local Text playerName;
local Text featureRealName;
local class featureClass;
featureClass = LoadFeatureClass(featureName);
if (featureClass == none) return;
if (callerPlayer == none) return;
featureRealName = _.text.FromClass(featureClass);
playerName = callerPlayer.GetName();
if (!featureClass.static.IsEnabled())
{
callerConsole
.Write(P("Feature "))
.UseColorOnce(_.color.TextEmphasis).Write(featureRealName)
.WriteLine(F(" is already {$TextNegative disabled}"));
_.memory.Free(featureRealName);
_.memory.Free(playerName);
return;
}
featureClass.static.DisableMe();
callerConsole
.Write(P("Feature "))
.UseColorOnce(_.color.TextEmphasis).Write(featureRealName)
.WriteLine(F(" is {$TextNegative disabled}"));
othersConsole
.Write(playerName).Write(F(" {$TextNegative disabled} feature "))
.UseColorOnce(_.color.TextEmphasis).WriteLine(featureRealName);
_.memory.Free(featureRealName);
_.memory.Free(playerName);
}
protected function class LoadFeatureClass(Text featureName)
{
local Text featureClassName;
local class featureClass;
if (featureName == none) {
return none;
}
if (featureName.StartsWith(P("$"))) {
featureClassName = _.alias.ResolveFeature(featureName, true);
}
else {
featureClassName = featureName.Copy();
}
featureClass = class(_.memory.LoadClass(featureClassName));
if (featureClass == none)
{
callerConsole
.Write(F("{$TextFailure Failed} to load feature `"))
.Write(featureName)
.WriteLine(P("`"));
}
_.memory.Free(featureClassName);
return featureClass;
}
protected function ShowAllFeatures()
{
local int i;
local CoreService service;
local array< class > availableFeatures;
service = CoreService(class'CoreService'.static.Require());
availableFeatures = service.GetAvailableFeatures();
for (i = 0; i < availableFeatures.length; i ++) {
ShowFeature(availableFeatures[i]);
}
}
protected function ShowFeature(class feature)
{
local int i;
local Text autoConfig;
local MutableText featureName, builder;
local ReportTool reportTool;
local array availableConfigs;
local class configClass;
if (feature == none) {
return;
}
configClass = feature.default.configClass;
if (configClass != none) {
availableConfigs = configClass.static.AvailableConfigs();
}
featureName = _.text
.FromClassM(feature)
.ChangeDefaultFormatting(
_.text.FormattingFromColor(_.color.TextEmphasis));
builder = _.text.Empty();
if (feature.static.IsEnabled()) {
builder.Append(F("[ {$TextPositive enabled} ] "));
}
else {
builder.Append(F("[ {$TextNegative disabled} ] "));
}
builder.Append(featureName);
_.memory.Free(featureName);
if (availableConfigs.length == 1) {
builder.Append(P(" with config:"));
}
else if (availableConfigs.length > 1) {
builder.Append(P(" with configs:"));
}
reportTool = ReportTool(_.memory.Allocate(class'ReportTool'));
reportTool.Initialize(builder);
_.memory.Free(builder);
autoConfig = configClass.static.GetAutoEnabledConfig();
for (i = 0; i < availableConfigs.length; i += 1)
{
builder = _.text.Empty().Append(availableConfigs[i]);
reportTool.Item(builder);
if ( autoConfig != none
&& autoConfig.Compare(availableConfigs[i], SCASE_INSENSITIVE))
{
reportTool.Detail(F("{$TextPositive auto enabled}"));
}
_.memory.Free(builder);
builder = none;
}
reportTool.Report(callerConsole);
_.memory.FreeMany(availableConfigs);
_.memory.Free(reportTool);
_.memory.Free(autoConfig);
}
defaultproperties
{
}