Freeciv21
Develop your civilization from humble roots to a global empire
server.h
Go to the documentation of this file.
1 /*
2  * (c) Copyright 2020 The Freeciv21 contributors
3  *
4  * This file is part of Freeciv21.
5  *
6  * Freeciv21 is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Freeciv21 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Freeciv21. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #pragma once
21 
22 #include "sernet.h"
23 
24 // Qt
25 #include <QLocalServer>
26 #include <QObject>
27 #include <QTcpServer>
28 
29 #include <atomic>
30 
31 #ifdef Q_OS_WIN
32 #include <QRecursiveMutex>
33 #include <QThread>
34 #endif // Q_OS_WIN
35 
36 class civtimer;
37 class QTcpServer;
38 class QTimer;
39 
40 namespace freeciv {
41 
42 #ifdef Q_OS_WIN
43 namespace detail {
47 class async_readline_wrapper final : public QThread {
48  Q_OBJECT
49 public:
50  async_readline_wrapper(bool interactive, QObject *parent = nullptr);
51 
52  void stop();
53 
54 public slots:
55  void wait_for_input();
56 
57 signals:
58  void line_available(const QString &line);
59 
60 private:
61  bool m_interactive; // Whether to use readline.
62  std::atomic<bool> m_stop;
63 };
64 } // namespace detail
65 #endif
66 
68 class server : public QObject {
69  Q_OBJECT
70 public:
71  explicit server();
72  ~server() override;
73 
74  bool is_ready() const;
75 
76 private slots:
77  // Low-level stuff
78  void error_on_socket();
79  void input_on_socket();
82  void send_pings();
83 
84  // Higher-level stuff
85  bool prepare_game();
86  void begin_turn();
87  void begin_phase();
88  void end_phase();
89  void end_turn();
90  void update_game_state();
91  bool shut_game_down();
92  void quit_idle();
93  void pulse();
94 
95 private:
96  void init_interactive();
97 
98 #ifdef Q_OS_WIN
99  // On Windows, we need a ton of additional functions to work around the
100  // lack of (constistent) notification system for stdin. Native Windows
101  // mechanisms work for either the console, named pipes, or files, but not
102  // all of them at once. So we resort to spawning a thread and making
103  // blocking calls, for which we need additional synchronization.
104 signals:
105  void input_requested();
106 private slots:
107  void input_on_stdin(const QString &line);
108 
109 private:
110  static QRecursiveMutex s_stdin_mutex;
111  static char **synchronized_completion(const char *text, int start,
112  int end);
113 #else // !Q_OS_WIN
114 private slots:
115  void input_on_stdin();
116 #endif // Q_OS_WIN
117 
118 private:
119  bool m_ready = false;
120 
121  bool m_interactive = false;
122  QObject *m_stdin_notifier = nullptr; // Actual type is OS-dependent
123 
125 
127 
130  int m_save_counter = 0;
131 
133  QTimer *m_quitidle_timer = nullptr;
134 
135  QTimer *m_pulse_timer = nullptr;
136 };
137 
138 } // namespace freeciv
A Freeciv21 server.
Definition: server.h:68
~server() override
Shut down a server.
Definition: server.cpp:361
bool m_skip_mapimg
Definition: server.h:129
socket_server m_server
Definition: server.h:124
void accept_local_connections()
Server accepts connections over local socket: Low level socket stuff, and basic-initialize the connec...
Definition: server.cpp:437
void init_interactive()
Initializes interactive handling of stdin with libreadline.
Definition: server.cpp:406
void begin_phase()
Do everything needed to start a new phase on top of calling begin_phase.
Definition: server.cpp:790
bool prepare_game()
Prepares for a new game.
Definition: server.cpp:739
server()
Creates a server.
Definition: server.cpp:269
civtimer * m_between_turns_timer
Definition: server.h:126
void pulse()
Called every second.
Definition: server.cpp:1109
void error_on_socket()
Called when there was an error on a socket.
Definition: server.cpp:600
void end_turn()
Do everything needed to end a turn on top of calling end_turn.
Definition: server.cpp:910
int m_save_counter
Definition: server.h:130
QObject * m_stdin_notifier
Definition: server.h:122
void input_on_socket()
Called when there's something to read on a socket.
Definition: server.cpp:629
bool m_interactive
Definition: server.h:121
QTimer * m_pulse_timer
Definition: server.h:135
bool shut_game_down()
Shuts a game down when all players have left.
Definition: server.cpp:1043
bool m_need_send_pending_events
Definition: server.h:128
bool m_ready
Definition: server.h:119
civtimer * m_eot_timer
Definition: server.h:126
void input_on_stdin()
Called when there's something to read on stdin.
Definition: server.cpp:704
bool m_someone_ever_connected
Definition: server.h:132
bool m_is_new_turn
Definition: server.h:128
void quit_idle()
Quit because we're idle (ie no one was connected in the last srvarg.quitidle seconds).
Definition: server.cpp:1072
void update_game_state()
Checks if the game state has changed and take action if appropriate.
Definition: server.cpp:964
void end_phase()
Do everything needed to end a phase on top of calling end_phase.
Definition: server.cpp:867
void send_pings()
Sends pings to clients if needed.
Definition: server.cpp:562
void accept_tcp_connections()
Server accepts connections from client: Low level socket stuff, and basic-initialize the connection s...
Definition: server.cpp:474
void begin_turn()
Do everything needed to start a new turn on top of calling begin_turn.
Definition: server.cpp:775
bool is_ready() const
Checks if the server is ready for the event loop to start.
Definition: server.cpp:431
QTimer * m_quitidle_timer
Definition: server.h:133
Definition: path.cpp:10
std::variant< std::unique_ptr< QTcpServer >, std::unique_ptr< QLocalServer > > socket_server
Definition: sernet.h:32