]> git.localhorst.tv Git - blank.git/blobdiff - src/shared/cli.cpp
impersonate command
[blank.git] / src / shared / cli.cpp
index 9663cb2c4efb192e5e7f0ee36768c84b737db437..c144d8677830281318f09585705168f0d9d3ca90 100644 (file)
@@ -5,6 +5,7 @@
 #include "../io/TokenStreamReader.hpp"
 #include "../world/Entity.hpp"
 #include "../world/Player.hpp"
+#include "../world/World.hpp"
 
 #include <iostream>
 #include <sstream>
@@ -18,6 +19,7 @@ namespace blank {
 CLI::CLI(World &world)
 : world(world)
 , commands() {
+       AddCommand("as", new ImpersonateCommand);
        AddCommand("tp", new TeleportCommand);
 }
 
@@ -63,14 +65,67 @@ CLI::Command::~Command() {
 }
 
 
+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();
+       }
+}
+
+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 &, 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 = ctx.GetPlayer().GetEntity().GetState();
+       EntityState state = ctx.GetEntity().GetState();
        state.pos = ExactLocation(pos).Sanitize();
-       ctx.GetPlayer().GetEntity().SetState(state);
+       ctx.GetEntity().SetState(state);
 
        stringstream msg;
-       msg << ctx.GetPlayer().Name() << " teleported to " << pos;
+       msg << ctx.GetEntity().Name() << " teleported to " << pos;
        ctx.Broadcast(msg.str());
 }