Tpserver-cpp/Admin
From Thousand Parsec Wiki
The remote administration project intends to remove the internal console from tpserver-cpp and replace it with a protocol which can be accessed by administration clients in a variety of useful ways. This is being developed for Google Summer of Code 2008 by Aaron Mavrinac / ezod.
Plan
Functional Milestones
- 2008-05-25: protocol specification document - complete
- 2008-06-02: tpserver-cpp will accept administration connections - complete
- 2008-06-02: tpserver-cpp will log to administration clients - complete
- 2008-06-06: tpserver-cpp will respond to requests for command lists and descriptions - complete
- 2008-06-13: tpserver-cpp will start as a daemon by default - complete
- 2008-06-20: tpserver-cpp will accept basic command set - complete
- 2008-06-20: tpadmin-cpp client will be able to connect to tpserver-cpp
- 2008-06-27: tpadmin-cpp client will support command frames
- 2008-07-07: tpserver-cpp will implement full command set
- 2008-07-14: libtpclient/libtpproto will include a partial admin client
- 2008-08-01: tpclient-pywx will be able to start and configure a server
- 2008-08-08: tpclient-pywx will include a single-player GUI wizard
- 2008-08-18: tpclient-pywx will check for AI clients, and be able to start and configure them
Planned Clients
- Main CLI client, written in C++, based on a minimal libtpproto-cpp.
- Single-player mode wizard in tpclient-pywx, based on libtpproto-py.
- Main GUI client, written in Python, based on libtpproto2-py.
Procedure
- Write a full administration protocol specification.
- Create
AdminTcpSocket,AdminConnection, andAdminTcpConnectionobjects. - Implement the protocol in the
AdminConnectionobject. - Create the main CLI client.
- Remove
Consoleobject and all associated code. - Daemonize the server and make a different logging option default.
- Remove libtprl dependency from packages.
Administration Protocol Extension
Overview
The administration client will connect and authenticate in a manner similar to the game protocol. Once connected, it may receive log messages and issue commands.
The main CLI client must store all available command descriptions locally (for command line verification, tab completion, etc.). It initially grabs the full current command set from the server upon a successful connection. After any operation which could result in new commands becoming available on the server, such as loading a ruleset, this local set must be updated.
Some command IDs are static and reserved for important server commands which all servers support. These include the commands which will be used by tpclient-pywx and other game clients to start a local server for single-player mode.
Summary
The following table contains both existing protocol frames and new administration-related frames (the latter are bold). The server must support all of these frame types and ignore others.
This protocol extension requires version 0.3 or greater of the TP protocol.
| Value | Name | Description | Base | Dir |
|---|---|---|---|---|
| Header Frame | any | |||
| Request Frame | Header | server | ||
| Response Frame | Header | client | ||
| 0 | Okay Frame | A request was successful in some sort of way. | Response | |
| 1 | Fail Frame | A request has failed in some sort of way. | Response | |
| 2 | Sequence Frame | Frame which says that there are multiple frames coming in response to the request. | Response | |
| 3 | Connect Frame | Request | ||
| 4 | Login Frame | Request | ||
| 1000 | Log Message Frame | Frame containing a log message to display at the client. | Header | client |
| 1001 | Command Update Frame | Frame instructing the client to pull command set descriptions. | Header | client |
| Get With ID Frame | Used to get things (commands) using their IDs. | Request | ||
| Get ID Sequence Frame | Request | |||
| ID Sequence Frame | A sequence of IDs. | Response | ||
| 1002 | Get Command Description Frame | Gets a description for a single command. | Get With ID | |
| 1003 | Command Description Frame | Frame describing a command. | Response | |
| 1004 | Get Command Description IDs Frame | Gets a sequence of active commands available on this server. | Get ID Sequence | |
| 1005 | List of Command Description IDs Frame | ID Sequence | ||
| 1006 | Command Frame | Issues a command to the server. | Request | |
| 1007 | Command Result Frame | Response frame with the result of the command. | Response |
Basic Command Set
These are the commands currently supported by the internal console.
QuitCommand
quit, exit
Quit and shutdown the server.
Network::getNetwork()->stopMainLoop();
EndTurnCommand
turn end
End the current turn now and start processing.
Logger::getLogger()->info("End Of Turn initiated from console");
Game::getGame()->getTurnTimer()->manuallyRunEndOfTurn();
TurnTimeCommand
turn time
The amount of time until the next turn.
std::cout << Game::getGame()->getTurnTimer()->secondsToEOT() << " seconds to EOT" << std::endl;
TurnResetCommand
turn reset
Reset the timer for the next turn.
Game::getGame()->getTurnTimer()->resetTimer(); std::cout << "Reset EOT timer, " << Game::getGame()->getTurnTimer()->secondsToEOT() << " seconds to EOT" << std::endl;
TurnLengthCommand
turn length tlen
Sets the turn length, but doesn't affect the current turn. Commented out.
uint32_t tlen = atoi(cmdline.c_str()); Game::getGame()->setTurnLength(tlen); std::cout << "Setting turn length to " << tlen << " seconds" << std::endl;
TurnNumberCommand
turn number
Gets the current turn number.
std::cout << "The current turn number is " << Game::getGame()->getTurnNumber() << std::endl;
NetworkStartCommand
network start
Starts the network listeners and accepts connections.
Network::getNetwork()->start();
NetworkStopCommand
network stop
Stops the network listeners and drops all connections.
Network::getNetwork()->stop();
SettingsSetCommand
settings set setting value
Sets a setting.
size_t pos1 = cmdline.find(' ');
Settings::getSettings()->set(cmdline.substr(0, pos1), cmdline.substr(pos1+1));
std::cout << "Setting value of \"" << cmdline.substr(0, pos1) << "\" to \"" << cmdline.substr(pos1+1) << "\"." << std::endl;
SettingsGetCommand
settings get setting
Gets a setting.
std::cout << "Setting \"" << cmdline << "\" is set to \"" << Settings::getSettings()->get(cmdline) << "\"." << std::endl;
PluginLoadCommand
plugin load plugin
Loads a plugin.
if(PluginManager::getPluginManager()->load(cmdline)){
std::cout << "Plugin \"" << cmdline << "\" was loaded." << std::endl;
}else{
std::cout << "Plugin \"" << cmdline << "\" was not loaded." << std::endl;
}
PluginListCommand
plugin list
Lists the plugins that are loaded.
std::cout << "These plugins are loaded: " << PluginManager::getPluginManager()->getLoadedLibraryNames() << std::endl;
GameRulesetCommand
game ruleset ruleset-name
Sets the ruleset to be used by ther server.
if(PluginManager::getPluginManager()->loadRuleset(cmdline)){
std::cout << "Ruleset \"" << cmdline << "\" was loaded." << std::endl;
}else{
std::cout << "Ruleset \"" << cmdline << "\" was not loaded." << std::endl;
}
GameTpschemeCommand
game tpscheme tpscheme-name
Sets the tpscheme implementation to be used by ther server.
if(PluginManager::getPluginManager()->loadTpScheme(cmdline)){
std::cout << "TpScheme implementation \"" << cmdline << "\" was loaded." << std::endl;
}else{
std::cout << "TpScheme implementation \"" << cmdline << "\" was not loaded." << std::endl;
}
GamePersistenceCommand
game persistence method
Sets the persistence method to be used by ther server.
if(PluginManager::getPluginManager()->loadPersistence(cmdline)){
std::cout << "Persistence method \"" << cmdline << "\" was loaded." << std::endl;
}else{
std::cout << "Persistence method \"" << cmdline << "\" was not loaded." << std::endl;
}
GameLoadCommand
game load
Loads the initial data for the game.
Game::getGame()->load();
GameStartCommand
game start
Starts the game and the end of turn timer.
Game::getGame()->start();
StatusCommand
status
Prints the key info about the server and game.
std::cout << "Server: tpserver-cpp" << std::endl;
std::cout << "Version: " VERSION << std::endl;
std::cout << "Persistence available: " << ((Game::getGame()->getPersistence() != NULL) ? "yes" : "no") << std::endl;
Ruleset* rules = Game::getGame()->getRuleset();
std::cout << "Ruleset Loaded: " << ((rules != NULL) ? "yes" : "no") << std::endl;
if(rules != NULL){
std::cout << "Ruleset Name: " << rules->getName() << std::endl;
std::cout << "Ruleset Version: " << rules->getVersion() << std:: endl;
}
std::cout << "Game Loaded: " << ((Game::getGame()->isLoaded()) ? "yes" : "no") << std::endl;
std::cout << "Game Started: " << ((Game::getGame()->isStarted()) ? "yes" : "no") << std::endl;
if(Game::getGame()->isStarted()){
std::cout << "Time to next turn: " << Game::getGame()->getTurnTimer()->secondsToEOT() << std::endl;
std::cout << "Turn length: " << Game::getGame()->getTurnTimer()->getTurnLength() << " seconds" << std::endl;
std::cout << "Turn number: " << Game::getGame()->getTurnNumber() << std::endl;
}
std::cout << "Network Started: " << ((Network::getNetwork()->isStarted()) ? "yes" : "no") << std::endl;
