made it so non-interactive mode works well with eras
This commit is contained in:
parent
ab34166bb2
commit
f50ee653d3
9 changed files with 79 additions and 36 deletions
17
src/game.cpp
17
src/game.cpp
|
@ -452,6 +452,7 @@ int play_game(int argc, char** argv)
|
|||
//it is all handled inside this 'if' statement
|
||||
if(multiplayer_mode) {
|
||||
|
||||
std::string era = "era_default";
|
||||
std::string scenario = "multiplayer_test";
|
||||
std::map<int,std::string> side_types, side_controllers, side_algorithms;
|
||||
std::map<int,string_map> side_parameters;
|
||||
|
@ -484,6 +485,8 @@ int play_game(int argc, char** argv)
|
|||
|
||||
if(name == "--scenario") {
|
||||
scenario = value;
|
||||
} else if(name == "--era") {
|
||||
era = value;
|
||||
} else if(last_digit && name_head == "--controller") {
|
||||
side_controllers[side] = value;
|
||||
} else if(last_digit && name_head == "--algorithm") {
|
||||
|
@ -518,9 +521,15 @@ int play_game(int argc, char** argv)
|
|||
config level = *lvl;
|
||||
std::vector<config*> story;
|
||||
|
||||
const config* const side = game_config.child("multiplayer_side");
|
||||
const config* const era_cfg = game_config.find_child("era","id",era);
|
||||
if(era_cfg == NULL) {
|
||||
std::cerr << "Could not find era '" << era << "'\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
const config* const side = era_cfg->child("multiplayer_side");
|
||||
if(side == NULL) {
|
||||
std::cerr << "Could not find side\n";
|
||||
std::cerr << "Could not find multiplayer side\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -535,8 +544,8 @@ int play_game(int argc, char** argv)
|
|||
controller = side_controllers.find(side_num),
|
||||
algorithm = side_algorithms.find(side_num);
|
||||
|
||||
const config* side = type == side_types.end() ? game_config.child("multiplayer_side") :
|
||||
game_config.find_child("multiplayer_side","type",type->second);
|
||||
const config* side = type == side_types.end() ? era_cfg->child("multiplayer_side") :
|
||||
era_cfg->find_child("multiplayer_side","type",type->second);
|
||||
if(side == NULL) {
|
||||
std::string side_name = (type == side_types.end() ? "default" : type->second);
|
||||
std::cerr << "Could not find side '" << side_name << "' for side " << side_num << "\n";
|
||||
|
|
|
@ -107,6 +107,8 @@ std::set<network::connection> bad_sockets;
|
|||
|
||||
namespace network {
|
||||
|
||||
const connection null_connection = 0;
|
||||
|
||||
error::error(const std::string& msg, connection sock) : message(msg), socket(sock)
|
||||
{
|
||||
if(socket) {
|
||||
|
|
|
@ -35,6 +35,8 @@ private:
|
|||
|
||||
typedef int connection;
|
||||
|
||||
extern const connection null_connection;
|
||||
|
||||
//the number of peers we are connected to
|
||||
size_t nconnections();
|
||||
|
||||
|
|
|
@ -339,6 +339,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
|
||||
int player_number = 0;
|
||||
|
||||
std::deque<config> data_backlog;
|
||||
|
||||
try {
|
||||
for(bool first_time = true; true; first_time = false, first_player = 0) {
|
||||
player_number = 0;
|
||||
|
@ -491,15 +493,27 @@ redo_turn:
|
|||
|
||||
for(;;) {
|
||||
|
||||
bool have_data = false;
|
||||
config cfg;
|
||||
|
||||
const network::connection res = network::receive_data(cfg);
|
||||
network::connection from = network::null_connection;
|
||||
|
||||
const turn_info::PROCESS_DATA_RESULT result = turn_data.process_network_data(cfg,res);
|
||||
if(result == turn_info::PROCESS_RESTART_TURN) {
|
||||
goto redo_turn;
|
||||
} else if(result == turn_info::PROCESS_END_TURN) {
|
||||
break;
|
||||
if(data_backlog.empty() == false) {
|
||||
have_data = true;
|
||||
cfg = data_backlog.front();
|
||||
data_backlog.pop_front();
|
||||
} else {
|
||||
from = network::receive_data(cfg);
|
||||
have_data = from != network::null_connection;
|
||||
}
|
||||
|
||||
if(have_data) {
|
||||
const turn_info::PROCESS_DATA_RESULT result = turn_data.process_network_data(cfg,from,data_backlog);
|
||||
if(result == turn_info::PROCESS_RESTART_TURN) {
|
||||
goto redo_turn;
|
||||
} else if(result == turn_info::PROCESS_END_TURN) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const int ncommand = recorder.ncommands();
|
||||
|
|
|
@ -134,7 +134,11 @@ void play_turn(game_data& gameinfo, game_state& state_of_game,
|
|||
try {
|
||||
config cfg;
|
||||
const network::connection res = network::receive_data(cfg);
|
||||
turn_data.process_network_data(cfg,res);
|
||||
std::deque<config> backlog;
|
||||
|
||||
if(res != network::null_connection) {
|
||||
turn_data.process_network_data(cfg,res,backlog);
|
||||
}
|
||||
|
||||
turn_data.turn_slice();
|
||||
} catch(end_level_exception& e) {
|
||||
|
@ -2063,12 +2067,8 @@ unit_map::const_iterator turn_info::current_unit() const
|
|||
return i;
|
||||
}
|
||||
|
||||
turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg, network::connection from)
|
||||
turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg, network::connection from, std::deque<config>& backlog)
|
||||
{
|
||||
if(from == 0) {
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
if(cfg.child("observer") != NULL) {
|
||||
const config::child_list& observers = cfg.get_children("observer");
|
||||
for(config::child_list::const_iterator ob = observers.begin(); ob != observers.end(); ++ob) {
|
||||
|
@ -2090,26 +2090,34 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
|
|||
bool turn_end = false;
|
||||
|
||||
const config::child_list& turns = cfg.get_children("turn");
|
||||
if(turns.empty() == false) {
|
||||
if(turns.empty() == false && from != network::null_connection) {
|
||||
//forward the data to other peers
|
||||
network::send_data_all_except(cfg,from);
|
||||
}
|
||||
|
||||
for(config::child_list::const_iterator t = turns.begin(); t != turns.end(); ++t) {
|
||||
|
||||
replay replay_obj(**t);
|
||||
replay_obj.start_replay();
|
||||
if(turn_end == false) {
|
||||
replay replay_obj(**t);
|
||||
replay_obj.start_replay();
|
||||
|
||||
try {
|
||||
turn_end |= do_replay(gui_,map_,gameinfo_,units_,teams_,
|
||||
team_num_,status_,state_of_game_,&replay_obj);
|
||||
} catch(replay::error& e) {
|
||||
save_game(string_table["network_sync_error"]);
|
||||
try {
|
||||
turn_end = do_replay(gui_,map_,gameinfo_,units_,teams_,
|
||||
team_num_,status_,state_of_game_,&replay_obj);
|
||||
} catch(replay::error& e) {
|
||||
save_game(string_table["network_sync_error"]);
|
||||
|
||||
//throw e;
|
||||
//throw e;
|
||||
}
|
||||
|
||||
recorder.add_config(**t,replay::MARK_AS_SENT);
|
||||
} else {
|
||||
|
||||
//this turn has finished, so push the remaining moves
|
||||
//into the backlog
|
||||
backlog.push_back(config());
|
||||
backlog.back().add_child("turn",**t);
|
||||
}
|
||||
|
||||
recorder.add_config(**t,replay::MARK_AS_SENT);
|
||||
}
|
||||
|
||||
//if a side has dropped out of the game.
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "unit.hpp"
|
||||
#include "video.hpp"
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
@ -77,8 +78,14 @@ public:
|
|||
|
||||
enum PROCESS_DATA_RESULT { PROCESS_CONTINUE, PROCESS_RESTART_TURN, PROCESS_END_TURN };
|
||||
|
||||
//function which will process incoming network data, and act on it.
|
||||
PROCESS_DATA_RESULT process_network_data(const config& cfg, network::connection from);
|
||||
//function which will process incoming network data, and act on it. If there is
|
||||
//more data than a single turn's worth, excess data will be placed into 'backlog'.
|
||||
//No more than one turn's worth of data will be placed into a single backlog item,
|
||||
//so it is safe to assume that backlog won't be touched if cfg is a member of a previous
|
||||
//backlog.
|
||||
//data will be forwarded to all peers other than 'from', unless 'from' is null, in
|
||||
//which case data will not be forwarded
|
||||
PROCESS_DATA_RESULT process_network_data(const config& cfg,network::connection from,std::deque<config>& backlog);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -142,6 +142,11 @@ void game::add_player(network::connection player)
|
|||
observer_join.add_child("observer").values["name"] = info->second.name();
|
||||
send_data(observer_join);
|
||||
}
|
||||
|
||||
//tell this player that the game has started
|
||||
config cfg;
|
||||
cfg.add_child("start_game");
|
||||
network::send_data(cfg,player);
|
||||
}
|
||||
|
||||
//if the player is already in the game, don't add them.
|
||||
|
@ -154,10 +159,7 @@ void game::add_player(network::connection player)
|
|||
send_user_list();
|
||||
|
||||
//send the player the history of the game to-date
|
||||
for(std::vector<config>::const_iterator i = history_.begin();
|
||||
i != history_.end(); ++i) {
|
||||
network::send_data(*i,player);
|
||||
}
|
||||
network::send_data(history_,player);
|
||||
}
|
||||
|
||||
void game::remove_player(network::connection player)
|
||||
|
@ -247,7 +249,7 @@ void game::send_data_team(const config& data, const std::string& team, network::
|
|||
|
||||
void game::record_data(const config& data)
|
||||
{
|
||||
history_.push_back(data);
|
||||
history_.append(data);
|
||||
}
|
||||
|
||||
bool game::level_init() const
|
||||
|
|
|
@ -82,7 +82,7 @@ private:
|
|||
|
||||
config level_;
|
||||
|
||||
std::vector<config> history_;
|
||||
config history_;
|
||||
|
||||
config* description_;
|
||||
|
||||
|
|
|
@ -301,7 +301,6 @@ void server::run()
|
|||
//g->start_game() will send data that assumes the [start_game]
|
||||
//message has been sent
|
||||
g->send_data(data,sock);
|
||||
g->record_data(data);
|
||||
|
||||
g->start_game();
|
||||
lobby_players_.send_data(sync_initial_response());
|
||||
|
|
Loading…
Add table
Reference in a new issue