X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fshared%2Fcli.cpp;h=c144d8677830281318f09585705168f0d9d3ca90;hb=cdd865c1934eccbb1f1d0ffaf041e53f0fdd524b;hp=6942f78704ec3a887dabff21fd35df37e0a6ba51;hpb=4727825186798902f68df5b99a6a32f0ef618454;p=blank.git diff --git a/src/shared/cli.cpp b/src/shared/cli.cpp index 6942f78..c144d86 100644 --- a/src/shared/cli.cpp +++ b/src/shared/cli.cpp @@ -1,12 +1,15 @@ #include "CLI.hpp" +#include "CLIContext.hpp" #include "commands.hpp" #include "../io/TokenStreamReader.hpp" #include "../world/Entity.hpp" #include "../world/Player.hpp" +#include "../world/World.hpp" #include #include +#include using namespace std; @@ -16,6 +19,7 @@ namespace blank { CLI::CLI(World &world) : world(world) , commands() { + AddCommand("as", new ImpersonateCommand); AddCommand("tp", new TeleportCommand); } @@ -29,7 +33,7 @@ void CLI::AddCommand(const string &name, Command *cmd) { commands[name] = cmd; } -void CLI::Execute(Player &player, const string &line) { +void CLI::Execute(CLIContext &ctx, const string &line) { stringstream s(line); TokenStreamReader args(s); if (!args.HasMore()) { @@ -37,44 +41,92 @@ void CLI::Execute(Player &player, const string &line) { return; } if (args.Peek().type != Token::IDENTIFIER) { - Error("I don't understand"); + ctx.Error("I don't understand"); return; } string name; args.ReadIdentifier(name); auto entry = commands.find(name); if (entry == commands.end()) { - Error(name + ": command not found"); + ctx.Error(name + ": command not found"); return; } try { - entry->second->Execute(*this, player, args); + entry->second->Execute(*this, ctx, args); } catch (exception &e) { - Error(name + ": " + e.what()); + ctx.Error(name + ": " + e.what()); } catch (...) { - Error(name + ": unknown execution error"); + ctx.Error(name + ": unknown execution error"); } } -void CLI::Message(const string &msg) { - // TODO: display message to player - cout << msg << endl; +CLI::Command::~Command() { + } -void CLI::Error(const string &msg) { - Message("CLI error: " + msg); + +CLIContext::CLIContext(Player *p, Entity *e) +: original_player(p) +, effective_player(p) +, original_entity(e) +, effective_entity(e) { + if (!e && p) { + original_entity = effective_entity = &p->GetEntity(); + } } -CLI::Command::~Command() { +std::string CLIContext::Name() const { + if (HasPlayer()) return GetPlayer().Name(); + if (HasEntity()) return GetEntity().Name(); + return "anonymous"; +} + + +void ImpersonateCommand::Execute(CLI &cli, CLIContext &ctx, TokenStreamReader &args) { + if (!args.HasMore()) { + // no argument => reset + ctx.Reset(); + ctx.Broadcast(ctx.Name() + " returned to their own self"); + return; + } + // TODO: broadcast who (real player name) impersonates who + string old_name = ctx.Name(); + string name(args.GetString()); + + Player *p = cli.GetWorld().FindPlayer(name); + if (p) { + ctx.SetPlayer(*p); + ctx.SetEntity(p->GetEntity()); + ctx.Broadcast(old_name + " now impersonating " + p->Name()); + return; + } + + // not a player, try an entity + Entity *e = cli.GetWorld().FindEntity(name); + if (e) { + ctx.SetEntity(*e); + ctx.Broadcast(old_name + " now impersonating " + e->Name()); + return; + } + ctx.Error("no player or entity with name " + name); } -void TeleportCommand::Execute(CLI &cli, Player &player, TokenStreamReader &args) { +void TeleportCommand::Execute(CLI &, CLIContext &ctx, TokenStreamReader &args) { + if (!ctx.HasEntity()) { + ctx.Error("teleport needs entity to operate on"); + return; + } + glm::vec3 pos(args.GetFloat(), args.GetFloat(), args.GetFloat()); - EntityState state = player.GetEntity().GetState(); + EntityState state = ctx.GetEntity().GetState(); state.pos = ExactLocation(pos).Sanitize(); - player.GetEntity().SetState(state); + ctx.GetEntity().SetState(state); + + stringstream msg; + msg << ctx.GetEntity().Name() << " teleported to " << pos; + ctx.Broadcast(msg.str()); } }