/* * server.h * Server class * ____ _ * | _ \ ___ __ _| |_ __ ___ ___ * | |_) / _ \/ _` | | '_ ` _ \/ __| * | _ < __/ (_| | | | | | | \__ \ * |_| \_\___|\__,_|_|_| |_| |_|___/ * * Copyright (C) 2007-2009 Jason Mitchell * Contributions by Tim Callahan, Jonathan Hseu * Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman * */ #ifndef SERVER_H_ #define SERVER_H_ // C Includes #include <netinet/in.h> // Needs: htons, htonl, INADDR_ANY, sockaddr_in class PythonHandler; class WebInterface; class Socket; class cmd; enum childType { CHILD_START, CHILD_DNS_RESOLVER, CHILD_LISTER, CHILD_DEMOGRAPHICS, CHILD_MOVEROOM_FIND, CHILD_MOVEROOM_FINISH, CHILD_FIND_SPACE, CHILD_END }; class Server { // ************** // Static Methods public: static Server* getInstance(); static void destroyInstance(); ~Server(); // Instance private: static Server* myInstance; protected: Server(); // ***************** // Public Structures public: struct controlSock { int port; int control; controlSock(int port, int control) { this->port = port; this->control = control; } }; struct childProcess { int pid; childType type; int fd; // Fd if any we should watch bstring extra; childProcess() { pid = 0; fd = -1; extra = ""; } childProcess(int p, childType t, int f = -1, bstring e = "") { pid = p; type = t; fd = f; extra = e; } }; struct dnsCache { bstring ip; bstring hostName; time_t time; dnsCache(bstring pIp, bstring pHostName, time_t pTime) { ip = pIp; hostName = pHostName; time = pTime; } bool operator==(const dnsCache& o) { return(ip == o.ip && hostName == o.hostName); } }; // Temp public public: std::map<bstring, Player*> players; // Map of all players std::list<Socket*> sockets; // List of all connected sockets // ****************** // Internal Variables private: std::list<BaseRoom*> effectsIndex; fd_set inSet; fd_set outSet; fd_set excSet; bool running; // True while the game is up and bound to a port long pulse; // Current pulse bool rebooting; bool GDB; bool valgrind; std::list<childProcess> children; // List of child processes std::list<controlSock> controlSocks; // List of control fds std::list<dnsCache> cachedDns; // Cache of DNS lookups WebInterface* webInterface; // Game Updates ctag *first_active; // The active list long lastDnsPrune; long lastUserUpdate; long lastRoomPulseUpdate; long lastRandomUpdate; long lastActiveUpdate; int Deadchildren; PythonHandler* pythonHandler; // **************** // Internal Methods private: // Python bool initPython(); bool cleanUpPython(); int getNumSockets(void); // Get number of sockets in the sockets list // Game & Socket methods int handleNewConnection(controlSock& control); int poll(void); // Poll all descriptors for input int checkNew(void); // Accept new connections int processInput(void); // Process input from users int processCommands(void); // Process commands from users int processChildren(void); int processListOutput(childProcess &lister); // Child processes void addChild(int pid, childType pType, int pFd = -1, bstring pExtra = ""); int reapChildren(void); // Clean up after any dead children // Reboot bool saveRebootFile(bool resetShips = false); // Updates void updateGame(void); void pulseTicks(long t); void pulseCreatureEffects(long t); void pulseRoomEffects(long t); void updateUsers(long t); void updateRandom(long t); void updateActive(long t); // DNS void addCache(bstring ip, bstring hostName, time_t t = -1); void saveDnsCache(); void loadDnsCache(); void pruneDns(); int installPrintfHandlers(); void installSignalHandlers(); // ******************************* // Public methods for server class public: // Python bool runPython(bstring pyScript, bstring args = "", MudObject *actor = NULL, MudObject *target = NULL); // Setup bool init(); // Setup the server void setGDB(); void setRebooting(); void setValgrind(); int run(void); // Run the server int addListenPort(int); // Add a new port to listen to // Status void sendCrash(); bool isRebooting(); bool isGDB(); bool isValgrind(); // Reboot bool startReboot(bool resetShips = false); int finishReboot(void); // Bring the mud back up from a reboot // DNS bstring getDnsCacheString(); bool getDnsCache(bstring &ip, bstring &hostName); int startDnsLookup(Socket* sock, sockaddr_in pAddr); // Start dns lookup on a socket // Players bool addPlayer(Player* player); Player* findPlayer(bstring name); bool clearPlayer(bstring name); int getNumPlayers(); // Sockets int deleteSocket(Socket* sock); void disconnectAll(void); int cleanUp(void); // Kick out any disconnectors and other general cleanup int processOutput(void); // Send any buffered output // Web Interface bool initWebInterface(); bool checkWebInterface(); void recreateFifos(); // Active list functions const ctag* getFirstActive(); void addActive(Monster* monster); void delActive(Monster* monster); bool isActive(Monster* monster); // Child Processes void childDied(); int getDeadChildren() const; int runList(Socket* sock, cmd* cmnd); bstring simpleChildRead(Server::childProcess &child); void isAvailableSpace(bstring mover, Range range, int flag); void isAvailableSpace(bstring mover, bool isSpace); // Room moving functions - use children bstring moveRoomName(); void finishMoveRoom(Player* player, bool online, CatRef origin, CatRef target); bool moveRoom(bstring mover, CatRef origin, CatRef target); void endMoveRoom(); void moveRoomInfo(Player* player); // Queries bool checkDuplicateName(Socket* sock, bool dis); bool checkDouble(Socket* sock); // Bans void checkBans(); // Broadcasts bstring getTimeZone(); // Effects void addEffectsIndex(BaseRoom* room); void removeEffectsIndex(BaseRoom* room); void removeEffectsOwner(const Creature* owner); }; #endif /*SERVER_H_*/