1 //  Copyright (C) 2011, 2015 Ben Asselstine
2 //
3 //  This program is free software; you can redistribute it and/or modify
4 //  it under the terms of the GNU General Public License as published by
5 //  the Free Software Foundation; either version 3 of the License, or
6 //  (at your option) any later version.
7 //
8 //  This program is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 //  GNU Library General Public License for more details.
12 //
13 //  You should have received a copy of the GNU General Public License
14 //  along with this program; if not, write to the Free Software
15 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 //  02110-1301, USA.
17 
18 #include "config.h"
19 #include <memory>
20 #include <iostream>
21 #include <glib.h>
22 #include <gtkmm.h>
23 #include <sigc++/trackable.h>
24 #include <sigc++/functors/mem_fun.h>
25 #include "gamehost-client.h"
26 #include "ucompose.hpp"
27 #include "profilelist.h"
28 #include "profile.h"
29 #include "recently-played-game-list.h"
30 #include "recently-played-game.h"
31 #include "GameScenario.h"
32 #include "ghs-client-tool.h"
33 
GhsClientTool(Glib::ustring host,int port,Profile * p,bool show_list,bool reload,Glib::ustring unhost,Glib::ustring file,bool terminate)34 GhsClientTool::GhsClientTool(Glib::ustring host, int port, Profile *p, bool show_list, bool reload, Glib::ustring unhost, Glib::ustring file, bool terminate)
35 {
36   d_host = host;
37   request_count = 0;
38   d_show_list = show_list;
39   d_reload = reload;
40   d_unhost = unhost;
41   d_file_to_host = file;
42   d_terminate = terminate;
43   GamehostClient *gamehostclient = GamehostClient::getInstance();
44   Profilelist *plist = Profilelist::getInstance();
45   new_profile = NULL;
46   if (p)
47     profile = p;
48   else
49     {
50       if (plist->size() > 0)
51         profile = plist->front();
52       else
53         {
54           new_profile = new Profile("admin");
55           profile = new_profile;
56         }
57     }
58   gamehostclient->client_could_not_connect.connect
59     (sigc::mem_fun(*this, &GhsClientTool::on_could_not_connect));
60   gamehostclient->client_connected.connect
61     (sigc::mem_fun(*this, &GhsClientTool::on_connected));
62   gamehostclient->client_forcibly_disconnected.connect
63     (sigc::mem_fun(*this, &GhsClientTool::on_connection_lost));
64   gamehostclient->start(host, port, profile);
65 }
66 
~GhsClientTool()67 GhsClientTool::~GhsClientTool()
68 {
69   GamehostClient::deleteInstance();
70   if (new_profile)
71     delete new_profile;
72 }
73 
on_got_list_response(RecentlyPlayedGameList * l,Glib::ustring err)74 void GhsClientTool::on_got_list_response(RecentlyPlayedGameList *l, Glib::ustring err)
75 {
76   request_count--;
77   if (err != "")
78     {
79       std::cerr << err << std::endl;
80       if (request_count == 0)
81         Gtk::Main::quit();
82       return;
83     }
84   Glib::ustring s = String::ucompose(ngettext ("Listing %1 game",
85                                                "Listing %1 games", l->size()),
86                                     l->size());
87   std::cout << s << std::endl;
88   for (RecentlyPlayedGameList::iterator i = l->begin(); i != l->end(); i++)
89     {
90       std::cout << std::endl;
91       RecentlyPlayedNetworkedGame *g =
92         dynamic_cast<RecentlyPlayedNetworkedGame*>(*i);
93       std::cout << _("Id:") << " " << g->getId() << std::endl;
94       std::cout << _("Name:") << " " << g->getName() << std::endl;
95       std::cout << _("Host:") << " " << g->getHost() << std::endl;
96       std::cout << _("Port:") << " " << g->getPort() << std::endl;
97       std::cout << _("Profile:") << " " << g->getProfileId() << std::endl;
98     }
99   delete l;
100   if (request_count == 0)
101     Gtk::Main::quit();
102   return;
103 }
104 
on_got_reload_response(Glib::ustring err)105 void GhsClientTool::on_got_reload_response(Glib::ustring err)
106 {
107   request_count--;
108   if (err != "")
109     std::cerr << err << std::endl;
110   if (request_count == 0)
111     Gtk::Main::quit();
112 }
113 
on_could_not_connect()114 void GhsClientTool::on_could_not_connect()
115 {
116   std::cerr << _("Could not connect to game list server") << std::endl;
117   exit(1);
118 }
119 
on_connection_lost()120 void GhsClientTool::on_connection_lost()
121 {
122   std::cerr << _("Server went away unexpectedly") << std::endl;
123   exit(1);
124 }
125 
on_got_unhost_response(Glib::ustring id,Glib::ustring err)126 void GhsClientTool::on_got_unhost_response(Glib::ustring id, Glib::ustring err)
127 {
128   request_count--;
129   if (err != "")
130     std::cerr << err << std::endl;
131   else
132     std::cerr <<
133       String::ucompose(_("Stopped hosting game %1"), id) << std::endl;
134   if (request_count == 0)
135     Gtk::Main::quit();
136 }
137 
on_got_host_game_response(Glib::ustring err,Glib::ustring file)138 void GhsClientTool::on_got_host_game_response(Glib::ustring err, Glib::ustring file)
139 {
140   request_count--;
141   if (err != "")
142     {
143       std::cerr << err << std::endl;
144       if (request_count == 0)
145         Gtk::Main::quit();
146       return;
147     }
148   GamehostClient *ghc = GamehostClient::getInstance();
149   ghc->received_map_response.connect
150     (sigc::hide<0>(sigc::mem_fun(*this, &GhsClientTool::on_game_hosted)));
151   ghc->send_map_file(file);
152 }
153 
on_game_hosted(guint32 port,Glib::ustring err)154 void GhsClientTool::on_game_hosted(guint32 port, Glib::ustring err)
155 {
156   request_count--;
157   if (err != "")
158     {
159       std::cerr << err << std::endl;
160       if (request_count == 0)
161         Gtk::Main::quit();
162       return;
163     }
164 
165   std::cerr << String::ucompose("The game is hosted at %1, port %2", d_host,
166                                 port) << std::endl;
167   if (request_count == 0)
168     Gtk::Main::quit();
169 }
170 
on_connected()171 void GhsClientTool::on_connected()
172 {
173   GamehostClient *gamehostclient = GamehostClient::getInstance();
174   if (d_show_list)
175     {
176       gamehostclient->received_game_list.connect
177         (sigc::mem_fun(*this, &GhsClientTool::on_got_list_response));
178       request_count++;
179       gamehostclient->request_game_list();
180     }
181 
182   if (d_reload)
183     {
184       request_count++;
185       gamehostclient->received_reload_response.connect
186         (sigc::mem_fun(*this, &GhsClientTool::on_got_reload_response));
187       gamehostclient->request_reload();
188     }
189 
190   if (d_unhost.empty() == false)
191     {
192       request_count++;
193       gamehostclient->received_unhost_response.connect
194         (sigc::mem_fun(*this, &GhsClientTool::on_got_unhost_response));
195       gamehostclient->request_game_unhost(d_unhost);
196     }
197 
198   if (d_file_to_host.empty() == false)
199     {
200       request_count++;
201       gamehostclient->received_host_response.connect
202         (sigc::bind(sigc::hide<0>(sigc::mem_fun(*this, &GhsClientTool::on_got_host_game_response)), d_file_to_host));
203       bool broken = false;
204       Glib::ustring n, com, id;
205       guint32 p, c;
206       GameScenario::loadDetails(d_file_to_host, broken, p, c, n, com, id);
207       if (broken == false)
208         gamehostclient->request_game_host(id);
209       else
210         {
211           request_count--;
212           std::cerr << String::ucompose("couldn't load %1", d_file_to_host)
213             << std::endl;
214         }
215     }
216   if (d_terminate)
217     gamehostclient->request_server_terminate();
218 }
219