/*
* 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_*/