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 #pragma once
19 #ifndef GAMEHOST_SERVER_H
20 #define GAMEHOST_SERVER_H
21 
22 #include "config.h"
23 
24 #include <memory>
25 #include <list>
26 #include <sigc++/trackable.h>
27 #include <sigc++/signal.h>
28 #include <glibmm.h>
29 
30 #include "timing.h"
31 #include "network-ghs-common.h"
32 
33 class NetworkServer;
34 class XML_Helper;
35 class Profile;
36 class GameScenario;
37 class HostedGame;
38 class HostGameRequest;
39 
40 class GamehostServer
41 {
42 public:
43 
44   //! Returns the singleton instance.  Creates a new one if neccessary.
45   static GamehostServer * getInstance();
46 
47   static const int TOO_MANY_PROFILES_AWAITING_MAPS = 100;
48   static const int ONE_HOUR_OLD = 60 * 60;
49 
50   //! Deletes the singleton instance.
51   static void deleteInstance();
52 
53   bool isListening();
54   void start(int port);
55 
56   void reload();
57 
58   //get functions
getHostname()59   Glib::ustring getHostname() const {return hostname;};
60 
61   //set functions
setHostname(Glib::ustring h)62   void setHostname(Glib::ustring h) {hostname = h;};
setMembers(std::list<Glib::ustring> profile_ids)63   void setMembers(std::list<Glib::ustring> profile_ids) {members = profile_ids;};
64 
65   // signals
66   sigc::signal<void, int> port_in_use;
67   sigc::signal<void> terminate_request_received;
68 
69   // statics
70   static std::list<Glib::ustring> load_members_from_file(Glib::ustring file);
71 
72 protected:
73   GamehostServer();
74   ~GamehostServer();
75 
76 private:
77   std::unique_ptr<NetworkServer> network_server;
78   Glib::ustring hostname;
79   std::list<HostGameRequest*> host_game_requests;
80   std::list<Glib::ustring> members;
81 
82   bool onGotMessage(void *conn, int type, Glib::ustring message);
83   void onConnectionLost();
84   void onConnectionMade();
85   sigc::connection on_timer_registered(Timing::timer_slot s, int msecs_interval);
86   void on_connected_to_gamelist_server_for_advertising_removal(Glib::ustring scenario_id);
87   void on_advertising_removal_response_received();
88   void on_connected_to_gamelist_server_for_advertising(HostedGame *game);
89   void on_advertising_response_received();
90   void on_child_setup();
91   bool loadProfile(Glib::ustring tag, XML_Helper *helper, Profile **profile);
92 
93   // helpers
94   void sendList(void *conn);
95   void unhost(void *conn, Glib::ustring profile_id, Glib::ustring scenario_id, Glib::ustring &err);
96   HostedGame* host(GameScenario *game_scenario, Profile *profile, Glib::ustring &err);
97   void run_game(GameScenario *game_scenario, Glib::Pid *child_pid, guint32 port, Glib::ustring &err);
98   void get_profile_and_scenario_id(Glib::ustring payload, Profile **profile, Glib::ustring &scenario_id, Glib::ustring &err);
99   guint32 get_free_port();
100   bool is_member(Glib::ustring profile_id);
101 
102   void cleanup_old_profiles_awaiting_maps(int stale = ONE_HOUR_OLD);
103   bool add_to_profiles_awaiting_maps(Profile *profile, Glib::ustring scenario_id);
104   Profile *remove_from_profiles_awaiting_maps(Glib::ustring scenario_id);
105   bool waitForGameToBeConnectable(guint32 port);
106 
107   //! A static pointer for the singleton instance.
108   static GamehostServer * s_instance;
109 
110 };
111 
112 #endif
113