changed network protocol to be more efficient.

(Not backwardly compatible. Includes server update)
This commit is contained in:
Dave White 2004-03-24 18:47:22 +00:00
parent 7ede232ef5
commit c419321bf3
6 changed files with 72 additions and 25 deletions

View file

@ -1323,12 +1323,12 @@ void config::apply_diff(const config& diff)
for(all_children_iterator j = (*i)->ordered_begin(); j != (*i)->ordered_end(); ++j) {
const std::pair<const std::string*,const config*> item = *j;
const child_map::iterator itor = children.find(*item.first);
if(itor == children.end() || index > itor->second.size()) {
child_list& v = children[*item.first];
if(index > v.size()) {
throw error("error in diff: could not find element '" + *item.first + "'");
}
itor->second.insert(itor->second.begin()+index,new config(*item.second));
v.insert(v.begin()+index,new config(*item.second));
}
}

View file

@ -200,7 +200,7 @@ struct config
//to cfg2.
config get_diff(const config& c) const;
void apply_diff(const config& diff);
void apply_diff(const config& diff); //throw error
//all the attributes of this node.
string_map values;

View file

@ -134,6 +134,9 @@ public:
return START_GAME;
} else if(reply.child("leave_game")) {
return GAME_CANCELLED;
} else if(reply.child("scenario_diff")) {
std::cerr << "received diff for scenario....applying...\n";
sides_.apply_diff(*reply.child("scenario_diff"));
} else {
sides_ = reply;
std::cerr << "got some sides. Current number of sides = " << sides_.get_children("side").size() << "," << reply.get_children("side").size() << "\n";

View file

@ -498,11 +498,15 @@ int mp_connect::gui_do()
int new_playergold = -1;
int cur_playergold = -1;
config orig_level = *level_;
for(;;) {
int mousex, mousey;
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
const bool left_button = mouse_flags&SDL_BUTTON_LMASK;
bool level_changed = false;
for(size_t n = 0; n != combos_team_.size(); ++n) {
config& side = **(sides.first+n);
@ -540,7 +544,8 @@ int mp_connect::gui_do()
side["controller"] = "network";
side["description"] = "";
}
network::send_data(*level_);
level_changed = true;
}
//Player race
@ -553,7 +558,7 @@ int mp_connect::gui_do()
for(string_map::const_iterator i = values.begin(); i != values.end(); ++i) {
side[i->first] = i->second;
}
network::send_data(*level_);
level_changed = true;
}
//Player team
@ -561,11 +566,11 @@ int mp_connect::gui_do()
std::stringstream str;
str << (combos_team_[n].selected()+1);
side["team_name"] = str.str();
network::send_data(*level_);
level_changed = true;
}
if(combos_color_[n].process(mousex, mousey, left_button)) {
network::send_data(*level_);
level_changed = true;
}
sliders_gold_[n].process();
@ -586,7 +591,7 @@ int mp_connect::gui_do()
(*sides.first[n])["gold"],
rect.x, rect.y);
update_rect(rect);
network::send_data(*level_);
level_changed = true;
}
}
}
@ -608,7 +613,7 @@ int mp_connect::gui_do()
si["description"] = string_table["ai_controlled"];
combos_type_[m].set_selected(2);
}
network::send_data(*level_);
level_changed = true;
}
launch_.enable(full_);
@ -651,6 +656,15 @@ int mp_connect::gui_do()
return status_;
}
if(level_changed) {
config diff;
diff.add_child("scenario_diff",level_->get_diff(orig_level));
network::send_data(diff);
orig_level = *level_;
}
gui_update();
update_positions();
update_network();

View file

@ -178,6 +178,9 @@ RESULT enter(display& disp, config& game_data)
if(data.child("gamelist")) {
game_data = data;
break;
} else if(data.child("gamelist_diff")) {
game_data.apply_diff(*data.child("gamelist_diff"));
break;
} else if(data.child("error")) {
throw network::error((*data.child("error"))["message"]);
} else if(data.child("message")) {

View file

@ -36,6 +36,9 @@ private:
config login_response_;
config initial_response_;
config old_initial_response_;
config sync_initial_response();
typedef std::map<network::connection,player> player_map;
player_map players_;
@ -51,9 +54,18 @@ server::server(int port) : net_manager_(), server_(port)
login_response_["version"] = game_config::version;
}
config server::sync_initial_response()
{
config res;
res.add_child("gamelist_diff",initial_response_.get_diff(old_initial_response_));
old_initial_response_ = initial_response_;
return res;
}
void server::run()
{
config& gamelist = initial_response_.add_child("gamelist");
old_initial_response_ = initial_response_;
for(;;) {
try {
@ -110,10 +122,11 @@ void server::run()
not_logged_in_.remove_player(sock);
lobby_players_.add_player(sock);
//currently update user list to all players who are in lobby
//(later may optimize to only send new login information
//to all but the new player)
lobby_players_.send_data(initial_response_);
//send the new player the entire list of games and players
network::send_data(initial_response_,sock);
//send other players in the lobby the update that the player has joined
lobby_players_.send_data(sync_initial_response(),sock);
} else if(lobby_players_.is_member(sock)) {
const config* const create_game = data.child("create_game");
@ -178,8 +191,14 @@ void server::run()
continue;
}
//if this is data describing changes to a game.
if(data.child("scenario_diff")) {
g->level().apply_diff(*data.child("scenario_diff"));
g->send_data(data,sock);
}
//if this is data describing the level for a game
if(data.child("side") != NULL) {
else if(data.child("side") != NULL) {
const bool is_init = g->level_init();
@ -193,8 +212,8 @@ void server::run()
config& desc = gamelist.add_child("game",g->level());
g->set_description(&desc);
//send all players in the lobby the list of games
lobby_players_.send_data(initial_response_);
//send all players in the lobby the update to the list of games
lobby_players_.send_data(sync_initial_response());
}
//record the new level data, and send to all players
@ -224,8 +243,6 @@ void server::run()
g->start_game();
} else if(data.child("leave_game")) {
const bool needed = g->is_needed(sock);
g->remove_player(sock);
lobby_players_.add_player(sock);
if(needed) {
@ -245,17 +262,27 @@ void server::run()
delete gamelist->remove_child("game",desc - vg.first);
}
//update the state of the lobby to players in it.
//We have to sync the state of the lobby because we can
//send it to the players leaving the game
lobby_players_.send_data(sync_initial_response());
//put the players back in the lobby and send
//them the game list and user list again
g->send_data(initial_response_);
lobby_players_.add_players(*g);
games_.erase(g);
}
std::cerr << "sending quitting player game list: " << initial_response_.get_children("user").size() << "\n";
std::cerr << initial_response_.write() << "\n";
//send the player who has quit the new game list
//now sync players in the lobby again, to remove the game
lobby_players_.send_data(sync_initial_response());
} else {
g->remove_player(sock);
lobby_players_.add_player(sock);
//send the player who has quit the game list
network::send_data(initial_response_,sock);
}
continue;
} else if(data["side_secured"].empty() == false) {
@ -307,7 +334,7 @@ void server::run()
//send all players the information that a player has logged
//out of the system
lobby_players_.send_data(initial_response_);
lobby_players_.send_data(sync_initial_response());
std::cerr << "done closing socket...\n";
}