cyphesis/tools/cycmd.cpp

1272 lines
36 KiB
C++
Raw Normal View History

2006-01-19 Al Riddoch <alriddoch@zepler.org> * aiclient/ClientAccount.cpp, aiclient/ClientAccount.h, aiclient/ClientConnection.cpp, aiclient/ClientConnection.h, aiclient/client.cpp, aiclient/client.h, client/BaseClient.cpp, client/BaseClient.h, client/CharacterClient.cpp, client/CharacterClient.h, client/ClientConnection.cpp, client/ClientConnection.h, client/CreatorClient.cpp, client/CreatorClient.h, client/ObserverClient.cpp, client/ObserverClient.h, client/Py_CreatorClient.cpp, client/Py_CreatorClient.h, client/client.cpp, client/define_world.cpp, client/define_world.h, common/Add.h, common/Affect.h, common/AtlasFileLoader.cpp, common/AtlasFileLoader.h, common/Attack.h, common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.cpp, common/BaseWorld.h, common/Burn.h, common/Chop.h, common/Connect.h, common/CustomOp.cpp, common/CustomOp.h, common/CustomOp_impl.h, common/Cut.h, common/Database.cpp, common/Database.h, common/Delve.h, common/Dig.h, common/Eat.h, common/FormattedXMLWriter.cpp, common/FormattedXMLWriter.h, common/Generic.h, common/Load.h, common/Monitor.h, common/Mow.h, common/Nourish.h, common/OOGThing.cpp, common/OOGThing.h, common/Property.cpp, common/Property.h, common/Property_impl.h, common/Save.h, common/Setup.h, common/Tick.h, common/Unseen.h, common/Update.h, common/Use.h, common/Wield.h, common/accountbase.cpp, common/accountbase.h, common/const.cpp, common/const.h, common/custom.cpp, common/debug.h, common/globals.cpp, common/globals.h, common/id.cpp, common/id.h, common/inheritance.cpp, common/inheritance.h, common/inheritance_impl.h, common/log.cpp, common/log.h, common/newid.cpp, common/nls.h, common/op_switch.h, common/operations.cpp, common/operations.h, common/random.h, common/refno.h, common/serialno.cpp, common/serialno.h, common/system.cpp, common/system.h, common/terrain_utils.cpp, common/terrain_utils.h, common/type_utils.h, common/types.h, common/utility.cpp, common/utility.h, modules/DateTime.cpp, modules/DateTime.h, modules/Location.cpp, modules/Location.h, modules/WorldTime.cpp, modules/WorldTime.h, physics/BBox.cpp, physics/BBox.h, physics/Collision.cpp, physics/Collision.h, physics/Quaternion.cpp, physics/Quaternion.h, physics/Vector3D.cpp, physics/Vector3D.h, physics/VectorPol.h, rulesets/Area.cpp, rulesets/Area.h, rulesets/AreaProperty.cpp, rulesets/AreaProperty.h, rulesets/ArithmeticScript.cpp, rulesets/ArithmeticScript.h, rulesets/BaseMind.cpp, rulesets/BaseMind.h, rulesets/CalendarProperty.cpp, rulesets/CalendarProperty.h, rulesets/Character.cpp, rulesets/Character.h, rulesets/Combat.cpp, rulesets/Combat.h, rulesets/Container.cpp, rulesets/Container.h, rulesets/Creator.cpp, rulesets/Creator.h, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/EntityProperties.cpp, rulesets/Entity_getLocation.h, rulesets/Fell.cpp, rulesets/Fell.h, rulesets/Food.cpp, rulesets/Food.h, rulesets/Line.cpp, rulesets/Line.h, rulesets/LineProperty.cpp, rulesets/LineProperty.h, rulesets/MemEntity.cpp, rulesets/MemEntity.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/MemMap_methods.h, rulesets/MindFactory.cpp, rulesets/MindFactory.h, rulesets/Missile.h, rulesets/Motion.cpp, rulesets/Motion.h, rulesets/Movement.cpp, rulesets/Movement.h, rulesets/Pedestrian.cpp, rulesets/Pedestrian.h, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_BBox.cpp, rulesets/Py_BBox.h, rulesets/Py_EntityWrapper.h, rulesets/Py_Location.cpp, rulesets/Py_Location.h, rulesets/Py_Map.cpp, rulesets/Py_Map.h, rulesets/Py_Mind.cpp, rulesets/Py_Mind.h, rulesets/Py_Object.cpp, rulesets/Py_Object.h, rulesets/Py_Operation.cpp, rulesets/Py_Operation.h, rulesets/Py_Oplist.cpp, rulesets/Py_Oplist.h, rulesets/Py_Optime.cpp, rulesets/Py_Optime.h, rulesets/Py_Point3D.cpp, rulesets/Py_Point3D.h, rulesets/Py_Property.cpp, rulesets/Py_Property.h, rulesets/Py_Quaternion.cpp, rulesets/Py_Quaternion.h, rulesets/Py_RootEntity.cpp, rulesets/Py_RootEntity.h, rulesets/Py_Statistics.cpp, rulesets/Py_Statistics.h, rulesets/Py_Task.cpp, rulesets/Py_Task.h, rulesets/Py_Thing.cpp, rulesets/Py_Thing.h, rulesets/Py_Vector3D.cpp, rulesets/Py_Vector3D.h, rulesets/Py_World.cpp, rulesets/Py_World.h, rulesets/Py_WorldTime.cpp, rulesets/Py_WorldTime.h, rulesets/PythonArithmeticScript.cpp, rulesets/PythonArithmeticScript.h, rulesets/PythonMindScript.cpp, rulesets/PythonMindScript.h, rulesets/PythonScript.cpp, rulesets/PythonScript.h, rulesets/PythonThingScript.cpp, rulesets/PythonThingScript.h, rulesets/PythonWrapper.cpp, rulesets/PythonWrapper.h, rulesets/Python_API.cpp, rulesets/Python_API.h, rulesets/Python_Script_Utils.h, rulesets/Script.cpp, rulesets/Script.h, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Statistics.cpp, rulesets/Statistics.h, rulesets/StatisticsProperty.cpp, rulesets/StatisticsProperty.h, rulesets/Structure.cpp, rulesets/Structure.h, rulesets/Task.cpp, rulesets/Task.h, rulesets/TaskScript.cpp, rulesets/TaskScript.h, rulesets/TerrainProperty.cpp, rulesets/TerrainProperty.h, rulesets/Thing.cpp, rulesets/Thing.h, rulesets/ThingFactory.cpp, rulesets/ThingFactory.h, rulesets/World.cpp, rulesets/World.h, rulesets/attributes.h, server/Account.cpp, server/Account.h, server/Admin.cpp, server/Admin.h, server/ArithmeticFactory.cpp, server/ArithmeticFactory.h, server/CommClient.cpp, server/CommClient.h, server/CommIdleSocket.cpp, server/CommIdleSocket.h, server/CommListener.cpp, server/CommListener.h, server/CommLocalClient.cpp, server/CommLocalClient.h, server/CommMDNSPublisher.cpp, server/CommMDNSPublisher.h, server/CommMaster.cpp, server/CommMaster.h, server/CommMetaClient.cpp, server/CommMetaClient.h, server/CommPSQLSocket.cpp, server/CommPSQLSocket.h, server/CommPeer.cpp, server/CommPeer.h, server/CommPeerListener.cpp, server/CommPeerListener.h, server/CommRemoteClient.cpp, server/CommRemoteClient.h, server/CommServer.cpp, server/CommServer.h, server/CommSlaveClient.cpp, server/CommSlaveClient.h, server/CommSlaveListener.cpp, server/CommSlaveListener.h, server/CommSocket.cpp, server/CommSocket.h, server/CommUnixListener.cpp, server/CommUnixListener.h, server/Connection.cpp, server/Connection.h, server/Connection_methods.h, server/EntityFactory.cpp, server/EntityFactory.h, server/ExternalMind.cpp, server/ExternalMind.h, server/Idle.cpp, server/Idle.h, server/Lobby.cpp, server/Lobby.h, server/Master.cpp, server/Master.h, server/Peer.cpp, server/Peer.h, server/Persistance.cpp, server/Persistance.h, server/PersistantThingFactory.cpp, server/PersistantThingFactory.h, server/PersistantThingFactory_impl.h, server/Persistor.cpp, server/Persistor.h, server/Persistor_impl.h, server/Player.cpp, server/Player.h, server/Restoration.cpp, server/Restoration.h, server/Restorer.cpp, server/Restorer.h, server/Restorer_impl.h, server/ScriptFactory.cpp, server/ScriptFactory.h, server/ServerRouting.cpp, server/ServerRouting.h, server/ServerRouting_methods.h, server/SlaveClientConnection.cpp, server/SlaveClientConnection.h, server/TaskFactory.cpp, server/TaskFactory.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h, server/server.cpp, server/server.h, server/slave.cpp, tests/Areatest.cpp, tests/BaseEntitytest.cpp, tests/Charactertest.cpp, tests/Containertest.cpp, tests/Creatortest.cpp, tests/EntityExerciser.h, tests/EntityFactorytest.cpp, tests/Entitytest.cpp, tests/Foodtest.cpp, tests/IGEntityExerciser.h, tests/Linetest.cpp, tests/Locationtest.cpp, tests/OOGThingtest.cpp, tests/Planttest.cpp, tests/Propertytest.cpp, tests/Stackabletest.cpp, tests/Structuretest.cpp, tests/Tasktest.cpp, tests/TestWorld.h, tests/Thingtest.cpp, tests/WorldTimetest.cpp, tests/Worldtest.cpp, tests/allOperations.h, tests/collisiontest.cpp, tests/consttest.cpp, tests/distancetest.cpp, tests/emergencetest.cpp, tests/inheritancetest.cpp, tests/logtest.cpp, tests/randomtest.cpp, tests/systemtest.cpp, tests/transformtest.cpp, tests/type_utilstest.cpp, tests/utilitytest.cpp, tools/AdminClient.cpp, tools/AdminClient.h, tools/cyaddrules.cpp, tools/cycmd.cpp, tools/cyconfig.cpp, tools/cyconvertrules.cpp, tools/cyctrl.cpp, tools/cydbload.cpp, tools/cydumprules.cpp, tools/cyisoload.cpp, tools/cyloadrules.cpp, tools/cypasswd.cpp, tools/cywatchdog.cpp: Replace the copyright and license statements with new versions that include disclaimer of warranty, and permit distribution under later versions of the GPL.
2006-01-19 02:17:06 +00:00
// Cyphesis Online RPG Server and AI Engine
// Copyright (C) 2001 Alistair Riddoch
2006-01-19 Al Riddoch <alriddoch@zepler.org> * aiclient/ClientAccount.cpp, aiclient/ClientAccount.h, aiclient/ClientConnection.cpp, aiclient/ClientConnection.h, aiclient/client.cpp, aiclient/client.h, client/BaseClient.cpp, client/BaseClient.h, client/CharacterClient.cpp, client/CharacterClient.h, client/ClientConnection.cpp, client/ClientConnection.h, client/CreatorClient.cpp, client/CreatorClient.h, client/ObserverClient.cpp, client/ObserverClient.h, client/Py_CreatorClient.cpp, client/Py_CreatorClient.h, client/client.cpp, client/define_world.cpp, client/define_world.h, common/Add.h, common/Affect.h, common/AtlasFileLoader.cpp, common/AtlasFileLoader.h, common/Attack.h, common/BaseEntity.cpp, common/BaseEntity.h, common/BaseWorld.cpp, common/BaseWorld.h, common/Burn.h, common/Chop.h, common/Connect.h, common/CustomOp.cpp, common/CustomOp.h, common/CustomOp_impl.h, common/Cut.h, common/Database.cpp, common/Database.h, common/Delve.h, common/Dig.h, common/Eat.h, common/FormattedXMLWriter.cpp, common/FormattedXMLWriter.h, common/Generic.h, common/Load.h, common/Monitor.h, common/Mow.h, common/Nourish.h, common/OOGThing.cpp, common/OOGThing.h, common/Property.cpp, common/Property.h, common/Property_impl.h, common/Save.h, common/Setup.h, common/Tick.h, common/Unseen.h, common/Update.h, common/Use.h, common/Wield.h, common/accountbase.cpp, common/accountbase.h, common/const.cpp, common/const.h, common/custom.cpp, common/debug.h, common/globals.cpp, common/globals.h, common/id.cpp, common/id.h, common/inheritance.cpp, common/inheritance.h, common/inheritance_impl.h, common/log.cpp, common/log.h, common/newid.cpp, common/nls.h, common/op_switch.h, common/operations.cpp, common/operations.h, common/random.h, common/refno.h, common/serialno.cpp, common/serialno.h, common/system.cpp, common/system.h, common/terrain_utils.cpp, common/terrain_utils.h, common/type_utils.h, common/types.h, common/utility.cpp, common/utility.h, modules/DateTime.cpp, modules/DateTime.h, modules/Location.cpp, modules/Location.h, modules/WorldTime.cpp, modules/WorldTime.h, physics/BBox.cpp, physics/BBox.h, physics/Collision.cpp, physics/Collision.h, physics/Quaternion.cpp, physics/Quaternion.h, physics/Vector3D.cpp, physics/Vector3D.h, physics/VectorPol.h, rulesets/Area.cpp, rulesets/Area.h, rulesets/AreaProperty.cpp, rulesets/AreaProperty.h, rulesets/ArithmeticScript.cpp, rulesets/ArithmeticScript.h, rulesets/BaseMind.cpp, rulesets/BaseMind.h, rulesets/CalendarProperty.cpp, rulesets/CalendarProperty.h, rulesets/Character.cpp, rulesets/Character.h, rulesets/Combat.cpp, rulesets/Combat.h, rulesets/Container.cpp, rulesets/Container.h, rulesets/Creator.cpp, rulesets/Creator.h, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/EntityProperties.cpp, rulesets/Entity_getLocation.h, rulesets/Fell.cpp, rulesets/Fell.h, rulesets/Food.cpp, rulesets/Food.h, rulesets/Line.cpp, rulesets/Line.h, rulesets/LineProperty.cpp, rulesets/LineProperty.h, rulesets/MemEntity.cpp, rulesets/MemEntity.h, rulesets/MemMap.cpp, rulesets/MemMap.h, rulesets/MemMap_methods.h, rulesets/MindFactory.cpp, rulesets/MindFactory.h, rulesets/Missile.h, rulesets/Motion.cpp, rulesets/Motion.h, rulesets/Movement.cpp, rulesets/Movement.h, rulesets/Pedestrian.cpp, rulesets/Pedestrian.h, rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_BBox.cpp, rulesets/Py_BBox.h, rulesets/Py_EntityWrapper.h, rulesets/Py_Location.cpp, rulesets/Py_Location.h, rulesets/Py_Map.cpp, rulesets/Py_Map.h, rulesets/Py_Mind.cpp, rulesets/Py_Mind.h, rulesets/Py_Object.cpp, rulesets/Py_Object.h, rulesets/Py_Operation.cpp, rulesets/Py_Operation.h, rulesets/Py_Oplist.cpp, rulesets/Py_Oplist.h, rulesets/Py_Optime.cpp, rulesets/Py_Optime.h, rulesets/Py_Point3D.cpp, rulesets/Py_Point3D.h, rulesets/Py_Property.cpp, rulesets/Py_Property.h, rulesets/Py_Quaternion.cpp, rulesets/Py_Quaternion.h, rulesets/Py_RootEntity.cpp, rulesets/Py_RootEntity.h, rulesets/Py_Statistics.cpp, rulesets/Py_Statistics.h, rulesets/Py_Task.cpp, rulesets/Py_Task.h, rulesets/Py_Thing.cpp, rulesets/Py_Thing.h, rulesets/Py_Vector3D.cpp, rulesets/Py_Vector3D.h, rulesets/Py_World.cpp, rulesets/Py_World.h, rulesets/Py_WorldTime.cpp, rulesets/Py_WorldTime.h, rulesets/PythonArithmeticScript.cpp, rulesets/PythonArithmeticScript.h, rulesets/PythonMindScript.cpp, rulesets/PythonMindScript.h, rulesets/PythonScript.cpp, rulesets/PythonScript.h, rulesets/PythonThingScript.cpp, rulesets/PythonThingScript.h, rulesets/PythonWrapper.cpp, rulesets/PythonWrapper.h, rulesets/Python_API.cpp, rulesets/Python_API.h, rulesets/Python_Script_Utils.h, rulesets/Script.cpp, rulesets/Script.h, rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Statistics.cpp, rulesets/Statistics.h, rulesets/StatisticsProperty.cpp, rulesets/StatisticsProperty.h, rulesets/Structure.cpp, rulesets/Structure.h, rulesets/Task.cpp, rulesets/Task.h, rulesets/TaskScript.cpp, rulesets/TaskScript.h, rulesets/TerrainProperty.cpp, rulesets/TerrainProperty.h, rulesets/Thing.cpp, rulesets/Thing.h, rulesets/ThingFactory.cpp, rulesets/ThingFactory.h, rulesets/World.cpp, rulesets/World.h, rulesets/attributes.h, server/Account.cpp, server/Account.h, server/Admin.cpp, server/Admin.h, server/ArithmeticFactory.cpp, server/ArithmeticFactory.h, server/CommClient.cpp, server/CommClient.h, server/CommIdleSocket.cpp, server/CommIdleSocket.h, server/CommListener.cpp, server/CommListener.h, server/CommLocalClient.cpp, server/CommLocalClient.h, server/CommMDNSPublisher.cpp, server/CommMDNSPublisher.h, server/CommMaster.cpp, server/CommMaster.h, server/CommMetaClient.cpp, server/CommMetaClient.h, server/CommPSQLSocket.cpp, server/CommPSQLSocket.h, server/CommPeer.cpp, server/CommPeer.h, server/CommPeerListener.cpp, server/CommPeerListener.h, server/CommRemoteClient.cpp, server/CommRemoteClient.h, server/CommServer.cpp, server/CommServer.h, server/CommSlaveClient.cpp, server/CommSlaveClient.h, server/CommSlaveListener.cpp, server/CommSlaveListener.h, server/CommSocket.cpp, server/CommSocket.h, server/CommUnixListener.cpp, server/CommUnixListener.h, server/Connection.cpp, server/Connection.h, server/Connection_methods.h, server/EntityFactory.cpp, server/EntityFactory.h, server/ExternalMind.cpp, server/ExternalMind.h, server/Idle.cpp, server/Idle.h, server/Lobby.cpp, server/Lobby.h, server/Master.cpp, server/Master.h, server/Peer.cpp, server/Peer.h, server/Persistance.cpp, server/Persistance.h, server/PersistantThingFactory.cpp, server/PersistantThingFactory.h, server/PersistantThingFactory_impl.h, server/Persistor.cpp, server/Persistor.h, server/Persistor_impl.h, server/Player.cpp, server/Player.h, server/Restoration.cpp, server/Restoration.h, server/Restorer.cpp, server/Restorer.h, server/Restorer_impl.h, server/ScriptFactory.cpp, server/ScriptFactory.h, server/ServerRouting.cpp, server/ServerRouting.h, server/ServerRouting_methods.h, server/SlaveClientConnection.cpp, server/SlaveClientConnection.h, server/TaskFactory.cpp, server/TaskFactory.h, server/TrustedConnection.cpp, server/TrustedConnection.h, server/WorldRouter.cpp, server/WorldRouter.h, server/server.cpp, server/server.h, server/slave.cpp, tests/Areatest.cpp, tests/BaseEntitytest.cpp, tests/Charactertest.cpp, tests/Containertest.cpp, tests/Creatortest.cpp, tests/EntityExerciser.h, tests/EntityFactorytest.cpp, tests/Entitytest.cpp, tests/Foodtest.cpp, tests/IGEntityExerciser.h, tests/Linetest.cpp, tests/Locationtest.cpp, tests/OOGThingtest.cpp, tests/Planttest.cpp, tests/Propertytest.cpp, tests/Stackabletest.cpp, tests/Structuretest.cpp, tests/Tasktest.cpp, tests/TestWorld.h, tests/Thingtest.cpp, tests/WorldTimetest.cpp, tests/Worldtest.cpp, tests/allOperations.h, tests/collisiontest.cpp, tests/consttest.cpp, tests/distancetest.cpp, tests/emergencetest.cpp, tests/inheritancetest.cpp, tests/logtest.cpp, tests/randomtest.cpp, tests/systemtest.cpp, tests/transformtest.cpp, tests/type_utilstest.cpp, tests/utilitytest.cpp, tools/AdminClient.cpp, tools/AdminClient.h, tools/cyaddrules.cpp, tools/cycmd.cpp, tools/cyconfig.cpp, tools/cyconvertrules.cpp, tools/cyctrl.cpp, tools/cydbload.cpp, tools/cydumprules.cpp, tools/cyisoload.cpp, tools/cyloadrules.cpp, tools/cypasswd.cpp, tools/cywatchdog.cpp: Replace the copyright and license statements with new versions that include disclaimer of warranty, and permit distribution under later versions of the GPL.
2006-01-19 02:17:06 +00:00
//
// This program 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; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "common/types.h"
#include "common/globals.h"
#include "common/Tick.h"
#include <Atlas/Objects/Encoder.h>
#include <Atlas/Net/Stream.h>
#include <Atlas/Objects/Decoder.h>
#include <Atlas/Codec.h>
#include <Atlas/Objects/Entity.h>
#include <Atlas/Objects/Anonymous.h>
#include <Atlas/Objects/Operation.h>
#include <varconf/config.h>
#include "common/Monitor.h"
#include "common/Connect.h"
#include "common/compose.hpp"
#include <skstream/skstream_unix.h>
#include <sigc++/connection.h>
#ifndef READLINE_CXX_SANE // defined in config.h
extern "C" {
#endif
#define USE_VARARGS
#define PREFER_STDARG
#include <readline/readline.h>
#include <readline/history.h>
#ifndef READLINE_CXX_SANE
}
#endif
#include <iostream>
#include <algorithm>
#include <cstdio>
using Atlas::Message::Element;
using Atlas::Message::MapType;
using Atlas::Message::ListType;
using Atlas::Objects::Root;
using Atlas::Objects::Operation::Appearance;
using Atlas::Objects::Operation::Create;
using Atlas::Objects::Operation::Delete;
using Atlas::Objects::Operation::Disappearance;
using Atlas::Objects::Operation::Get;
using Atlas::Objects::Operation::Set;
using Atlas::Objects::Operation::Look;
using Atlas::Objects::Operation::Login;
using Atlas::Objects::Operation::Logout;
using Atlas::Objects::Operation::Talk;
using Atlas::Objects::Operation::Tick;
using Atlas::Objects::Operation::RootOperation;
using Atlas::Objects::Entity::RootEntity;
using Atlas::Objects::Entity::Anonymous;
using Atlas::Objects::smart_dynamic_cast;
using Atlas::Objects::Operation::Monitor;
using Atlas::Objects::Operation::Connect;
struct command {
const char * cmd_string;
const char * cmd_description;
};
struct command commands[] = {
{ "add_agent", "Create an in-game agent", },
{ "connect", "Connect server to a peer", },
{ "cancel", "Cancel the current admin task", },
{ "get", "Examine a class on the server", },
{ "find_by_name", "Find an entity with the given name", },
{ "find_by_type", "Find an entity with the given type", },
{ "flush", "Flush entities from the server", },
{ "help", "Display this help", },
{ "install", "Install a new type", },
{ "look", "Return the current server lobby", },
{ "logout", "Log user out of server", },
{ "monitor", "Enable in-game op monitoring", },
{ "query", "Examine an object on the server", },
{ "reload", "Reload the script for a type", },
{ "stat", "Return current server status", },
{ "unmonitor", "Disable in-game op monitoring", },
{ NULL, "Guard", }
};
2001-06-04 11:22:27 +00:00
static void help()
{
size_t max_length = 0;
for (struct command * I = &commands[0]; I->cmd_string != NULL; ++I) {
max_length = std::max(max_length, strlen(I->cmd_string));
}
max_length += 2;
std::cout << "Cyphesis commands:" << std::endl << std::endl;
for (struct command * I = &commands[0]; I->cmd_string != NULL; ++I) {
std::cout << " " << I->cmd_string
<< std::string(max_length - strlen(I->cmd_string), ' ')
<< I->cmd_description << std::endl;
}
std::cout << std::endl << std::flush;
}
class AdminTask {
protected:
bool m_complete;
AdminTask() : m_complete(false) { }
public:
virtual ~AdminTask() { }
virtual void setup(const std::string & arg, OpVector &) = 0;
virtual void operation(const RootOperation &, OpVector &) = 0;
bool isComplete() const { return m_complete; }
};
class Flusher : public AdminTask {
protected:
const std::string agentId;
std::string type;
public:
explicit Flusher(const std::string & agent_id) : agentId(agent_id) { }
void setup(const std::string & arg, OpVector & ret) {
type = arg;
Look l;
Anonymous lmap;
lmap->setParents(std::list<std::string>(1, type));
l->setArgs1(lmap);
l->setFrom(agentId);
ret.push_back(l);
}
void operation(const RootOperation & op, OpVector & res) {
if (op->getClassNo() == Atlas::Objects::Operation::SIGHT_NO) {
// We have a sight op, check if its the sight of an entity we
// want to delete.
const std::vector<Root> & args = op->getArgs();
if (args.empty()) {
std::cerr << "Got empty sight" << std::endl << std::flush;
return;
}
const Root & arg = args.front();
assert(arg.isValid());
RootEntity sight_ent = smart_dynamic_cast<RootEntity>(arg);
if (!sight_ent.isValid()) {
return;
}
if (!sight_ent->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
std::cerr << "Got sight no ID" << std::endl << std::flush;
return;
}
if (!sight_ent->hasAttrFlag(Atlas::Objects::PARENTS_FLAG)) {
std::cerr << "Got sight no PARENTS" << std::endl << std::flush;
return;
}
if (sight_ent->getParents().empty() ||
sight_ent->getParents().front() != type) {
return;
}
const std::string & id = sight_ent->getId();
std::cout << "Deleting: " << type << "(" << id << ")"
<< std::endl << std::flush;
Delete d;
Anonymous dmap;
dmap->setId(id);
d->setArgs1(dmap);
d->setFrom(agentId);
d->setTo(id);
res.push_back(d);
Tick t;
t->setFrom(agentId);
t->setTo(agentId);
t->setFutureSeconds(0.1);
t->setAttr("sub_to", "flusher");
res.push_back(t);
} else if (op->getParents().front() == "tick") {
// We have a tick op, check if its the one we sent ourselves
// to schedule the next look.
Element val;
if (op->copyAttr("sub_to", val) != 0 ||
!val.isString() || val.String() != "flusher") {
std::cout << "Not for us" << std::endl << std::flush;
return;
}
Look l;
Anonymous lmap;
lmap->setParents(std::list<std::string>(1, type));
l->setArgs1(lmap);
l->setFrom(agentId);
res.push_back(l);
} else if (op->getParents().front() == "unseen") {
// We have an unseen op, which signals our last look returned
// no results.
m_complete = true;
}
}
};
class OperationMonitor : public AdminTask {
protected:
int op_count;
int start_time;
public:
int count() {
return op_count;
}
int startTime() {
return start_time;
}
virtual void setup(const std::string & arg, OpVector &) {
struct timeval tv;
gettimeofday(&tv, NULL);
start_time = tv.tv_sec;
op_count = 0;
}
virtual void operation(const RootOperation & op, OpVector &) {
++op_count;
std::cout << op->getParents().front() << "(from=\"" << op->getFrom()
<< "\",to=\"" << op->getTo() << "\")"
<< std::endl << std::flush;
}
};
template <class Stream>
class Interactive : public Atlas::Objects::ObjectsDecoder,
virtual public sigc::trackable
{
private:
bool error_flag, reply_flag, login_flag, avatar_flag, server_flag;
int cli_fd;
Atlas::Objects::ObjectsEncoder * encoder;
Atlas::Codec * codec;
Stream ios;
std::string password;
std::string username;
std::string accountType;
std::string accountId;
std::string agentId;
std::string agentName;
std::string serverName;
std::string systemType;
std::string prompt;
bool exit;
AdminTask * currentTask;
void output(const Element & item, int depth = 0);
protected:
void objectArrived(const Atlas::Objects::Root &);
void appearanceArrived(const RootOperation &);
void disappearanceArrived(const RootOperation &);
void infoArrived(const RootOperation &);
void errorArrived(const RootOperation &);
void sightArrived(const RootOperation &);
void soundArrived(const RootOperation &);
int negotiate();
void updatePrompt();
public:
Interactive() : error_flag(false), reply_flag(false), login_flag(false),
avatar_flag(false), server_flag(false), encoder(0),
codec(0), serverName("cyphesis"), prompt("cyphesis> "),
exit(false), currentTask(0)
{ }
~Interactive() {
if (encoder != 0) {
delete encoder;
}
if (codec != 0) {
delete codec;
}
}
void send(const RootOperation &);
int connect(const std::string & host);
int login();
int setup();
void exec(const std::string & cmd, const std::string & arg);
void loop();
void poll(bool rewrite_prompt = true);
void getLogin();
void runCommand(char *);
int runTask(AdminTask * task, const std::string & arg);
int endTask();
void setPassword(const std::string & passwd) {
password = passwd;
}
void setUsername(const std::string & uname) {
username = uname;
}
static void gotCommand(char *);
};
template <class Stream>
void Interactive<Stream>::output(const Element & item, int depth)
{
switch (item.getType()) {
case Element::TYPE_INT:
std::cout << item.Int();
break;
case Element::TYPE_FLOAT:
std::cout << item.Float();
break;
case Element::TYPE_STRING:
std::cout << "\"" << item.String() << "\"";
break;
case Element::TYPE_LIST:
{
std::cout << "[ ";
ListType::const_iterator I = item.List().begin();
ListType::const_iterator Iend = item.List().end();
for(; I != Iend; ++I) {
output(*I, depth);
std::cout << " ";
}
std::cout << "]";
}
break;
case Element::TYPE_MAP:
{
std::cout << "{" << std::endl << std::flush;
MapType::const_iterator I = item.Map().begin();
MapType::const_iterator Iend = item.Map().end();
for(; I != Iend; ++I) {
std::cout << std::string((depth + 1) * 4, ' ') << I->first << ": ";
output(I->second, depth + 1);
std::cout << std::endl;
}
std::cout << std::string(depth * 4, ' ') << "}";
}
break;
default:
std::cout << "(\?\?\?)";
break;
}
}
template <class Stream>
void Interactive<Stream>::objectArrived(const Atlas::Objects::Root & obj)
{
RootOperation op = Atlas::Objects::smart_dynamic_cast<RootOperation>(obj);
if (!op.isValid()) {
std::cerr << "Non op object received from client" << std::endl << std::flush;
if (!obj->isDefaultParents() && !obj->getParents().empty()) {
std::cerr << "NOTICE: Unexpected object has parent "
<< obj->getParents().front()
<< std::endl << std::flush;
}
if (!obj->isDefaultObjtype()) {
std::cerr << "NOTICE: Unexpected object has objtype "
<< obj->getObjtype()
<< std::endl << std::flush;
}
return;
}
if (currentTask != 0) {
OpVector res;
currentTask->operation(op, res);
OpVector::const_iterator Iend = res.end();
for (OpVector::const_iterator I = res.begin(); I != Iend; ++I) {
encoder->streamObjectsMessage(*I);
}
ios << std::flush;
if (currentTask->isComplete()) {
delete currentTask;
currentTask = 0;
}
}
switch (op->getClassNo()) {
case Atlas::Objects::Operation::APPEARANCE_NO:
appearanceArrived(op);
break;
case Atlas::Objects::Operation::DISAPPEARANCE_NO:
disappearanceArrived(op);
break;
case Atlas::Objects::Operation::INFO_NO:
infoArrived(op);
break;
case Atlas::Objects::Operation::ERROR_NO:
errorArrived(op);
break;
case Atlas::Objects::Operation::SIGHT_NO:
sightArrived(op);
break;
case Atlas::Objects::Operation::SOUND_NO:
soundArrived(op);
break;
default:
break;
}
}
template <class Stream>
void Interactive<Stream>::appearanceArrived(const RootOperation & op)
{
if (accountId.empty()) {
return;
}
if (accountId != op->getTo()) {
// This is an IG op we are monitoring
return;
}
if (op->getArgs().empty()) {
return;
}
RootEntity ent = smart_dynamic_cast<RootEntity>(op->getArgs().front());
if (!ent.isValid()) {
std::cerr << "Got Appearance of non-entity" << std::endl << std::flush;
return;
}
if (!ent->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
std::cerr << "Got Appearance of non-string ID" << std::endl << std::flush;
return;
}
const std::string & id = ent->getId();
std::cout << "Appearance(id: " << id << ")";
if (!ent->hasAttrFlag(Atlas::Objects::Entity::LOC_FLAG)) {
std::cout << std::endl << std::flush;
return;
}
const std::string & loc = ent->getLoc();
std::cout << " in " << loc << std::endl;
if (loc == "lobby") {
std::cout << id << " has logged in." << std::endl;
}
std::cout << std::flush;
}
template <class Stream>
void Interactive<Stream>::disappearanceArrived(const RootOperation & op)
{
if (accountId.empty()) {
return;
}
if (accountId != op->getTo()) {
// This is an IG op we are monitoring
return;
}
if (op->getArgs().empty()) {
return;
}
RootEntity ent = smart_dynamic_cast<RootEntity>(op->getArgs().front());
if (!ent.isValid()) {
std::cerr << "Got Disappearance of non-entity" << std::endl << std::flush;
return;
}
if (!ent->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
std::cerr << "Got Disappearance of non-string ID" << std::endl << std::flush;
return;
}
const std::string & id = ent->getId();
std::cout << "Disappearance(id: " << id << ")";
if (!ent->hasAttrFlag(Atlas::Objects::Entity::LOC_FLAG)) {
std::cout << std::endl << std::flush;
return;
}
const std::string & loc = ent->getLoc();
std::cout << " in " << loc << std::endl;
if (loc == "lobby") {
std::cout << id << " has logged out." << std::endl;
}
std::cout << std::flush;
}
template <class Stream>
void Interactive<Stream>::infoArrived(const RootOperation & op)
{
reply_flag = true;
if (op->getArgs().empty()) {
return;
}
const Root & ent = op->getArgs().front();
if (login_flag) {
std::cout << "login success" << std::endl << std::flush;
if (!ent->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
std::cerr << "ERROR: Response to login does not contain account id"
<< std::endl << std::flush;
} else {
accountId = ent->getId();
}
if (ent->hasAttrFlag(Atlas::Objects::PARENTS_FLAG)) {
const std::list<std::string> & parents = ent->getParents();
if (!parents.empty()) {
accountType = parents.front();
}
}
} else if (avatar_flag) {
std::cout << "Create agent success" << std::endl << std::flush;
if (!ent->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
std::cerr << "ERROR: Response to agent create does not contain agent id"
<< std::endl << std::flush;
} else {
agentId = ent->getId();
avatar_flag = false;
}
} else if (server_flag) {
std::cout << "Server query success" << std::endl << std::flush;
if (!ent->isDefaultName()) {
serverName = ent->getName();
std::string::size_type p = serverName.find(".");
if (p != std::string::npos) {
serverName = serverName.substr(0, p);
}
updatePrompt();
}
Element raw_attr;
if (ent->copyAttr("server", raw_attr) == 0) {
if (raw_attr.isString()) {
systemType = raw_attr.String();
updatePrompt();
}
}
server_flag = false;
} else {
std::cout << "Info(" << std::endl;
MapType entmap = ent->asMessage();
MapType::const_iterator Iend = entmap.end();
for (MapType::const_iterator I = entmap.begin(); I != Iend; ++I) {
const Element & item = I->second;
std::cout << " " << I->first << ": ";
output(item, 1);
std::cout << std::endl;
}
std::cout << ")" << std::endl << std::flush;
// Display results of command
}
}
template <class Stream>
void Interactive<Stream>::errorArrived(const RootOperation & op)
{
reply_flag = true;
error_flag = true;
std::cout << "Error(";
const std::vector<Root> & args = op->getArgs();
const Root & arg = args.front();
Element message_attr;
if (arg->copyAttr("message", message_attr) == 0 && message_attr.isString()) {
std::cout << message_attr.asString();
}
std::cout << ")" << std::endl << std::flush;
}
template <class Stream>
void Interactive<Stream>::sightArrived(const RootOperation & op)
{
if (accountId.empty()) {
return;
}
if (accountId != op->getTo() && agentId != op->getTo()) {
// This is an IG op we are monitoring
return;
}
reply_flag = true;
std::cout << "Sight(" << std::endl;
const MapType & ent = op->getArgs().front()->asMessage();
MapType::const_iterator Iend = ent.end();
for (MapType::const_iterator I = ent.begin(); I != Iend; ++I) {
const Element & item = I->second;
std::cout << " " << I->first << ":";
output(item, 1);
std::cout << std::endl;
}
std::cout << ")" << std::endl << std::flush;
}
template <class Stream>
void Interactive<Stream>::soundArrived(const RootOperation & op)
{
if (accountId.empty()) {
return;
}
if (accountId != op->getTo()) {
// This is an IG op we are monitoring
return;
}
reply_flag = true;
const MapType & arg = op->getArgs().front()->asMessage();
MapType::const_iterator I = arg.find("from");
if (I == arg.end() || !I->second.isString()) {
std::cout << "Sound arg has no from" << std::endl << std::flush;
return;
}
const std::string & from = I->second.asString();
I = arg.find("args");
if (I == arg.end() || !I->second.isList()
|| I->second.asList().empty()
|| !I->second.asList().front().isMap()) {
std::cout << "Sound arg has no args" << std::endl << std::flush;
return;
}
const MapType & ent = I->second.asList().front().asMap();
I = ent.find("say");
if (I == ent.end() || !I->second.isString()) {
std::cout << "Sound arg arg has no say" << std::endl << std::flush;
return;
}
const std::string & say = I->second.asString();
std::cout << "[" << from << "] " << say
<< std::endl << std::flush;
}
sigc::signal<void, char *> CmdLine;
template <class Stream>
void Interactive<Stream>::gotCommand(char * cmd)
{
CmdLine.emit(cmd);
}
template <class Stream>
void Interactive<Stream>::runCommand(char * cmd)
{
if (cmd == NULL) {
exit = true;
std::cout << std::endl << std::flush;
return;
}
if (*cmd == 0) {
free(cmd);
return;
}
add_history(cmd);
char * arg = strchr(cmd, ' ');
if (arg != NULL) {
*arg++ = 0;
int len = strlen(arg);
while ((len > 0) && (arg[--len] == ' ')) { arg[len] = 0; }
} else {
arg = "";
}
exec(cmd, arg);
}
template <class Stream>
int Interactive<Stream>::runTask(AdminTask * task, const std::string & arg)
{
assert(task != 0);
if (currentTask != 0) {
std::cout << "Busy" << std::endl << std::flush;
return -1;
}
currentTask = task;
OpVector res;
currentTask->setup(arg, res);
OpVector::const_iterator Iend = res.end();
for (OpVector::const_iterator I = res.begin(); I != Iend; ++I) {
encoder->streamObjectsMessage(*I);
}
return 0;
}
template <class Stream>
int Interactive<Stream>::endTask()
{
if (currentTask == 0) {
return -1;
}
delete currentTask;
currentTask = 0;
return 0;
}
int completion_iterator = 0;
char * completion_generator(const char * text, int state)
{
if (state == 0) {
completion_iterator = 0;
}
for (int i = completion_iterator; commands[i].cmd_string != 0; ++i) {
if (strncmp(text, commands[i].cmd_string, strlen(text)) == 0) {
completion_iterator = i + 1;
return strdup(commands[i].cmd_string);
}
}
return 0;
}
template <class Stream>
void Interactive<Stream>::loop()
{
rl_callback_handler_install(prompt.c_str(),
&Interactive<Stream>::gotCommand);
rl_completion_entry_function = &completion_generator;
CmdLine.connect(sigc::mem_fun(this, &Interactive<Stream>::runCommand));
while (!exit) {
poll();
};
std::cout << std::endl << std::flush;
rl_callback_handler_remove();
}
template <class Stream>
void Interactive<Stream>::poll(bool rewrite_prompt)
// poll the codec if select says there is something there.
{
fd_set infds;
struct timeval tv;
FD_ZERO(&infds);
FD_SET(cli_fd, &infds);
FD_SET(STDIN_FILENO, &infds);
tv.tv_sec = 0;
tv.tv_usec = 100000;
int retval = select(cli_fd+1, &infds, NULL, NULL, &tv);
if (retval) {
if (FD_ISSET(cli_fd, &infds)) {
if (ios.peek() == -1) {
std::cout << "Server disconnected" << std::endl << std::flush;
exit = true;
} else {
if (rewrite_prompt) {
std::cout << std::endl;
}
codec->poll();
if (rewrite_prompt) {
rl_forced_update_display();
}
}
}
if (FD_ISSET(STDIN_FILENO, &infds)) {
rl_callback_read_char();
}
}
}
template <class Stream>
void Interactive<Stream>::getLogin()
{
// This needs to be re-written to hide input, so the password can be
// secret
std::cout << "Username: " << std::flush;
std::cin >> username;
std::cout << "Password: " << std::flush;
std::cin >> password;
}
template<>
int Interactive<tcp_socket_stream>::connect(const std::string & host)
{
std::cout << "Connecting... " << std::flush;
ios.open(host, client_port_num);
if (!ios.is_open()) {
std::cout << "failed." << std::endl << std::flush;
return -1;
}
std::cout << "done." << std::endl << std::flush;
cli_fd = ios.getSocket();
return negotiate();
}
template<>
int Interactive<unix_socket_stream>::connect(const std::string & filename)
{
std::cout << "Connecting... " << std::flush;
ios.open(filename);
if (!ios.is_open()) {
std::cout << "failed." << std::endl << std::flush;
return -1;
}
std::cout << "done." << std::endl << std::flush;
cli_fd = ios.getSocket();
return negotiate();
}
template <class Stream>
int Interactive<Stream>::negotiate()
{
// Do client negotiation with the server
Atlas::Net::StreamConnect conn("cycmd", ios);
std::cout << "Negotiating... " << std::flush;
while (conn.getState() == Atlas::Negotiate::IN_PROGRESS) {
// conn.poll() does all the negotiation
conn.poll();
}
std::cout << "done." << std::endl << std::flush;
// Check whether negotiation was successful
if (conn.getState() == Atlas::Negotiate::FAILED) {
std::cerr << "Failed to negotiate." << std::endl;
return -1;
}
// Negotiation was successful
// Get the codec that negotiation established
codec = conn.getCodec(*this);
// Create the encoder
encoder = new Atlas::Objects::ObjectsEncoder(*codec);
// Send whatever codec specific data marks the beginning of a stream
codec->streamBegin();
return 0;
}
template <class Stream>
void Interactive<Stream>::updatePrompt()
{
std::string designation(">");
if (!username.empty()) {
prompt = username + "@";
if (accountType == "admin") {
designation = "#";
} else {
designation = "$";
}
} else {
prompt = "";
}
prompt += serverName;
prompt += " ";
prompt += systemType;
prompt += designation;
prompt += " ";
rl_set_prompt(prompt.c_str());
}
template <class Stream>
int Interactive<Stream>::login()
{
Atlas::Objects::Entity::Account account;
Login l;
error_flag = false;
reply_flag = false;
login_flag = true;
account->setAttr("username", username);
account->setAttr("password", password);
l->setArgs1(account);
encoder->streamObjectsMessage(l);
* tools/cycmd.cpp: Ensure that login op is flushed after it is sent. * server/Player.cpp: Arg order of std::string.compare() is incompatable between recent libstdc++ versions. Switch back to old version, still in most common use. * rulesets/Thing.cpp: Set refno on ops handled in game. * rulesets/Python_API.cpp: Modify Entity() python constructor so that commonly used attributes from old atlas are translated to their modern equivalents. * rulesets/Py_Thing.cpp, rulesets/Py_Mind.cpp: Differentiate between previously identical error messages in several places. * rulesets/Py_Object.cpp: Rework conversion of python dict to Atlas map to be more efficient and clean. * rulesets/Py_Location.cpp: Rework setting of vector parts of location so that it can accept vectors from python in more formats, including lists and tuples. * rulesets/Creator.h, rulesets/Character.h, common/BaseEntity.h: Re-order virtual methods declarations to fit a convention. * common/stringstream.h: Hardcode use of local stringstream class, as the version provided with older libstdc++ seems to be broken. * common/database.cpp: Use the common header to pick the right stringstream implementation. * common/BaseWorld.cpp, server/Persistance.cpp: Removed unused stringstream include. * rulesets/Creator.cpp: Added extra debug output. * client/define_world.h, client/define_world.cpp, client/CommClient.h: Use CreatorClient to store Creators mind, instead of BaseMind. * client/client.cpp, client/ObserverClient.h, client/ObserverClient.cpp, client/CreatorClient.h, client/CommClient.h, client/CommClient.cpp: Modify method names to fit capitalisation conventions. * client/CreatorClient.cpp: Implement creation of in-game entities, using creator entity. * client/CommClient.cpp: Added correct client side monitoring of creator entity. * client/ClientConnection.h, client/ClientConnection.cpp: Added pending method to establish if ops are in the queue. Switched send() method so we only send ops. Add setting of serialno of sent ops, starting with an offset of 512. * client/CharacterClient.h: Removed unused member, opFound. * client/CharacterClient.cpp: Debugged sendAndWait() method. Al Riddoch <alriddoch@zepler.org>
2001-08-16 17:39:42 +00:00
ios << std::flush;
while (!reply_flag) {
codec->poll();
}
login_flag = false;
if (!error_flag) {
updatePrompt();
return 0;
}
return -1;
}
template <class Stream>
int Interactive<Stream>::setup()
{
Get get;
encoder->streamObjectsMessage(get);
ios << std::flush;
server_flag = true;
reply_flag = true;
while (server_flag && !error_flag) {
codec->poll();
}
server_flag = false;
if (!error_flag) {
return 0;
}
return -1;
}
template <class Stream>
void Interactive<Stream>::exec(const std::string & cmd, const std::string & arg)
{
bool reply_expected = true;
reply_flag = false;
error_flag = false;
if (cmd == "stat") {
Get g;
encoder->streamObjectsMessage(g);
} else if (cmd == "install") {
size_t space = arg.find(' ');
if ((space == std::string::npos) || (space >= (arg.size() - 1))) {
std::cout << "usage: install <type id> <parent id>"
<< std::endl << std::flush;
} else {
Create c;
c->setFrom(accountId);
Anonymous ent;
ent->setId(std::string(arg, 0, space));
ent->setObjtype("class");
ent->setParents(std::list<std::string>(1, std::string(arg, space + 1)));
c->setArgs1(ent);
encoder->streamObjectsMessage(c);
}
reply_expected = false;
} else if (cmd == "look") {
Look l;
l->setFrom(accountId);
encoder->streamObjectsMessage(l);
} else if (cmd == "logout") {
Logout l;
l->setFrom(accountId);
if (!arg.empty()) {
Anonymous lmap;
lmap->setId(arg);
l->setArgs1(lmap);
reply_expected = false;
}
encoder->streamObjectsMessage(l);
} else if (cmd == "say") {
Talk t;
Anonymous ent;
ent->setAttr("say", arg);
t->setArgs1(ent);
t->setFrom(accountId);
encoder->streamObjectsMessage(t);
} else if ((cmd == "help") || (cmd == "?")) {
reply_expected = false;
help();
} else if (cmd == "query") {
Get g;
Anonymous cmap;
cmap->setObjtype("obj");
if (!arg.empty()) {
cmap->setId(arg);
}
g->setArgs1(cmap);
g->setFrom(accountId);
encoder->streamObjectsMessage(g);
} else if (cmd == "reload") {
if (arg.empty()) {
reply_expected = false;
std::cout << "reload: Argument required" << std::endl << std::flush;
} else {
Set s;
Anonymous tmap;
tmap->setObjtype("class");
tmap->setId(arg);
s->setArgs1(tmap);
s->setFrom(accountId);
encoder->streamObjectsMessage(s);
}
} else if (cmd == "get") {
Get g;
Anonymous cmap;
cmap->setObjtype("class");
if (!arg.empty()) {
cmap->setId(arg);
}
g->setArgs1(cmap);
g->setFrom(accountId);
encoder->streamObjectsMessage(g);
} else if (cmd == "monitor") {
AdminTask * task = new OperationMonitor;
if (runTask(task, arg) == 0) {
Monitor m;
m->setArgs1(Anonymous());
m->setFrom(accountId);
encoder->streamObjectsMessage(m);
}
reply_expected = false;
} else if (cmd == "unmonitor") {
OperationMonitor * om = dynamic_cast<OperationMonitor *>(currentTask);
if (om != 0) {
Monitor m;
m->setFrom(accountId);
encoder->streamObjectsMessage(m);
reply_expected = false;
struct timeval tv;
gettimeofday(&tv, NULL);
int monitor_time = tv.tv_sec - om->startTime();
std::cout << om->count() << " operations monitored in "
<< monitor_time << " seconds = "
<< om->count() / monitor_time
<< " operations per second"
<< std::endl << std::flush;
endTask();
}
} else if (cmd == "connect") {
reply_expected = false;
Connect m;
Anonymous cmap;
cmap->setAttr("hostname", arg);
m->setArgs1(cmap);
m->setFrom(accountId);
encoder->streamObjectsMessage(m);
} else if (cmd == "add_agent") {
Create c;
Anonymous cmap;
cmap->setParents(std::list<std::string>(1, "creator"));
cmap->setName("cycmd agent");
cmap->setObjtype("obj");
c->setArgs1(cmap);
c->setFrom(accountId);
avatar_flag = true;
encoder->streamObjectsMessage(c);
} else if (cmd == "find_by_name") {
if (agentId.empty()) {
std::cout << "Use add_agent to add an in-game agent first" << std::endl << std::flush;
reply_expected = false;
} else if (arg.empty()) {
std::cout << "Please specify the name to search for" << std::endl << std::flush;
reply_expected = false;
} else {
Look l;
Anonymous lmap;
lmap->setName(arg);
l->setArgs1(lmap);
l->setFrom(agentId);
encoder->streamObjectsMessage(l);
reply_expected = false;
}
} else if (cmd == "find_by_type") {
if (agentId.empty()) {
std::cout << "Use add_agent to add an in-game agent first" << std::endl << std::flush;
reply_expected = false;
} else if (arg.empty()) {
std::cout << "Please specify the type to search for" << std::endl << std::flush;
reply_expected = false;
} else {
Look l;
Anonymous lmap;
lmap->setParents(std::list<std::string>(1, arg));
l->setArgs1(lmap);
l->setFrom(agentId);
encoder->streamObjectsMessage(l);
reply_expected = false;
}
} else if (cmd == "flush") {
if (agentId.empty()) {
std::cout << "Use add_agent to add an in-game agent first" << std::endl << std::flush;
reply_expected = false;
} else if (arg.empty()) {
std::cout << "Please specify the type to flush" << std::endl << std::flush;
reply_expected = false;
} else {
AdminTask * task = new Flusher(agentId);
runTask(task, arg);
reply_expected = false;
}
} else if (cmd == "cancel") {
if (endTask() != 0) {
std::cout << "No task currently running" << std::endl << std::flush;
}
} else {
reply_expected = false;
std::cout << cmd << ": Command not known" << std::endl << std::flush;
}
ios << std::flush;
if (!reply_expected) { return; }
// Wait for reply
time_t wait_start_time = time(NULL);
while (!reply_flag) {
if (time(NULL) - wait_start_time > 5) {
std::cout << cmd << ": No reply from server" << std::endl << std::flush;
return;
}
poll(false);
}
}
2001-06-04 11:22:27 +00:00
static void usage(char * prg)
{
std::cerr << "usage: " << prg << " [ cmd [ server ] ]" << std::endl << std::flush;
}
int main(int argc, char ** argv)
{
int optind;
if ((optind = loadConfig(argc, argv)) < 0) {
// Fatal error loading config file
return 1;
}
std::string server;
if (global_conf->findItem("client", "serverhost")) {
server = global_conf->getItem("client", "serverhost").as_string();
}
int useslave = 0;
if (global_conf->findItem("client", "useslave")) {
useslave = global_conf->getItem("client", "useslave");
}
bool interactive = true;
std::string cmd;
if (optind < argc) {
if ((argc - optind) == 2) {
server = argv[optind + 1];
} else if ((argc - optind) > 2) {
usage(argv[0]);
return 1;
}
cmd = argv[optind];
interactive = false;
}
if (server.empty()) {
std::string localSocket = var_directory + "/tmp/";
if (useslave != 0) {
localSocket += slave_socket_name;
} else {
localSocket += client_socket_name;
}
std::cout << "Attempting local connection" << std::endl << std::flush;
Interactive<unix_socket_stream> bridge;
if (bridge.connect(localSocket) == 0) {
bridge.setUsername("admin");
bridge.setup();
std::cout << "Logging in... " << std::flush;
if (bridge.login() != 0) {
std::cout << "failed." << std::endl << std::flush;
bridge.getLogin();
std::cout << "Logging in... " << std::flush;
if (!bridge.login()) {
std::cout << "failed." << std::endl << std::flush;
return 1;
}
}
std::cout << "done." << std::endl << std::flush;
if (!interactive) {
bridge.exec(cmd, "");
return 0;
* aiclient/ClientConnection.cpp, aiclient/client.cpp, client/ClientConnection.cpp, common/database.h, common/globals.cpp, common/persistance.cpp, common/stringstream.h, server/CommClient.cpp, server/CommServer.cpp, server/Persistance.cpp, tools/cyctrl.cpp, tools/cyctrl.cpp, tools/cydbload.cpp, tools/cyisoload.cpp, tools/cypasswd.cpp: Removed unused config.h. * client/ObserverClient.cpp, common/const.h, tools/cycmd.cpp: Use default password if the admin account cannot be fetched from the database. * client/Py_CreatorClient.cpp, common/BaseEntity.cpp, common/BaseEntity.h, rulesets/Character.cpp, rulesets/Creator.cpp, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/EntityFactory.cpp, rulesets/MemMap.cpp, rulesets/Py_Mind.cpp, rulesets/Py_Thing.cpp, rulesets/Py_World.cpp, rulesets/Thing.cpp, server/Account.cpp, server/Admin.cpp, server/Connection.cpp, tools/cywatchdog.cpp: Make many of the member variables of Entity protected, and add the required accessors. Changed the name of the id attribute to m_id. * common/BaseWorld.h, common/database.cpp, common/persistance.cpp: Removed unused includes. * common/Chop.h, common/Cut.h, common/Eat.h, common/Fire.h, common/Generic.h, common/Load.h, common/Nourish.h, common/Save.h, common/Setup.h, common/Tick.h: Moved definition of virtual functions into cpp file, to reduce wasted code. * common/Makefile.am: Create cyphesis library, which can be used by other applications to access cyphesis databases. * common/config.h, common/database.h, server/Persistance.cpp, tools/cydbload.cpp, tools/cyisoload.cpp, tools/cypasswd.cpp: Remove conditional compilation of db code. db3 is now required. * server/WorldRouter.h: Fixed getNewId() so it take const string. * server/server.cpp: Removed python shutdown, so it does not mess up the db if it causes a segfault. Al Riddoch <alriddoch@zepler.org>
2001-10-17 14:09:42 +00:00
} else {
bridge.loop();
* aiclient/ClientConnection.cpp, aiclient/client.cpp, client/ClientConnection.cpp, common/database.h, common/globals.cpp, common/persistance.cpp, common/stringstream.h, server/CommClient.cpp, server/CommServer.cpp, server/Persistance.cpp, tools/cyctrl.cpp, tools/cyctrl.cpp, tools/cydbload.cpp, tools/cyisoload.cpp, tools/cypasswd.cpp: Removed unused config.h. * client/ObserverClient.cpp, common/const.h, tools/cycmd.cpp: Use default password if the admin account cannot be fetched from the database. * client/Py_CreatorClient.cpp, common/BaseEntity.cpp, common/BaseEntity.h, rulesets/Character.cpp, rulesets/Creator.cpp, rulesets/Entity.cpp, rulesets/Entity.h, rulesets/EntityFactory.cpp, rulesets/MemMap.cpp, rulesets/Py_Mind.cpp, rulesets/Py_Thing.cpp, rulesets/Py_World.cpp, rulesets/Thing.cpp, server/Account.cpp, server/Admin.cpp, server/Connection.cpp, tools/cywatchdog.cpp: Make many of the member variables of Entity protected, and add the required accessors. Changed the name of the id attribute to m_id. * common/BaseWorld.h, common/database.cpp, common/persistance.cpp: Removed unused includes. * common/Chop.h, common/Cut.h, common/Eat.h, common/Fire.h, common/Generic.h, common/Load.h, common/Nourish.h, common/Save.h, common/Setup.h, common/Tick.h: Moved definition of virtual functions into cpp file, to reduce wasted code. * common/Makefile.am: Create cyphesis library, which can be used by other applications to access cyphesis databases. * common/config.h, common/database.h, server/Persistance.cpp, tools/cydbload.cpp, tools/cyisoload.cpp, tools/cypasswd.cpp: Remove conditional compilation of db code. db3 is now required. * server/WorldRouter.h: Fixed getNewId() so it take const string. * server/server.cpp: Removed python shutdown, so it does not mess up the db if it causes a segfault. Al Riddoch <alriddoch@zepler.org>
2001-10-17 14:09:42 +00:00
}
return 0;
}
server = "localhost";
}
std::cerr << "Attempting tcp connection" << std::endl << std::flush;
Interactive<tcp_socket_stream> bridge;
if (bridge.connect(server) != 0) {
return 1;
}
bridge.setup();
if (!interactive) {
std::cerr << "WARNING: No login details available for remote host"
<< std::endl
<< "WARNING: Attempting command without logging in"
<< std::endl << std::flush;
} else {
bridge.getLogin();
std::cout << "Logging in... " << std::flush;
if (bridge.login() != 0) {
std::cout << "failed." << std::endl << std::flush;
return 1;
}
std::cout << "done." << std::endl << std::flush;
}
if (!interactive) {
bridge.exec(cmd, "");
} else {
bridge.loop();
}
delete global_conf;
return 0;
}