diff options
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/core/core.h | 4 | ||||
-rw-r--r-- | src/network/core/tcp.cpp | 2 | ||||
-rw-r--r-- | src/network/network.cpp | 33 | ||||
-rw-r--r-- | src/network/network.h | 2 | ||||
-rw-r--r-- | src/network/network_client.cpp | 37 | ||||
-rw-r--r-- | src/network/network_data.cpp | 2 | ||||
-rw-r--r-- | src/network/network_data.h | 121 | ||||
-rw-r--r-- | src/network/network_func.h | 63 | ||||
-rw-r--r-- | src/network/network_gamelist.cpp | 1 | ||||
-rw-r--r-- | src/network/network_gamelist.h | 2 | ||||
-rw-r--r-- | src/network/network_gui.cpp | 10 | ||||
-rw-r--r-- | src/network/network_gui.h | 5 | ||||
-rw-r--r-- | src/network/network_internal.h | 156 | ||||
-rw-r--r-- | src/network/network_server.cpp | 88 | ||||
-rw-r--r-- | src/network/network_server.h | 13 | ||||
-rw-r--r-- | src/network/network_type.h | 108 | ||||
-rw-r--r-- | src/network/network_udp.cpp | 2 |
17 files changed, 406 insertions, 243 deletions
diff --git a/src/network/core/core.h b/src/network/core/core.h index 54ff156f3..4c5b3f9bd 100644 --- a/src/network/core/core.h +++ b/src/network/core/core.h @@ -62,7 +62,7 @@ public: * Whether this socket is currently bound to a socket. * @return true when the socket is bound, false otherwise */ - bool IsConnected() { return this->sock != INVALID_SOCKET; } + bool IsConnected() const { return this->sock != INVALID_SOCKET; } /** * Whether the current client connected to the socket has quit. @@ -70,7 +70,7 @@ public: * data), the socket in not closed; only the packet is dropped. * @return true when the current client has quit, false otherwise */ - bool HasClientQuit() { return this->has_quit; } + bool HasClientQuit() const { return this->has_quit; } void Send_GRFIdentifier(Packet *p, const GRFIdentifier *grf); void Recv_GRFIdentifier(Packet *p, GRFIdentifier *grf); diff --git a/src/network/core/tcp.cpp b/src/network/core/tcp.cpp index f44f1741c..6450d4778 100644 --- a/src/network/core/tcp.cpp +++ b/src/network/core/tcp.cpp @@ -11,7 +11,7 @@ #include "../../openttd.h" #include "../../variables.h" -#include "../network_data.h" +#include "../network_internal.h" #include "packet.h" #include "tcp.h" diff --git a/src/network/network.cpp b/src/network/network.cpp index 77003e6a1..b0ab7a612 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -3,7 +3,7 @@ /** @file network.cpp Base functions for networking support. */ #include "../stdafx.h" -#include "network_data.h" +#include "../player_type.h" #ifdef ENABLE_NETWORK @@ -15,6 +15,7 @@ #include "../variables.h" #include "../date_func.h" #include "../newgrf_config.h" +#include "network_internal.h" #include "network_client.h" #include "network_server.h" #include "network_udp.h" @@ -38,7 +39,6 @@ #ifdef DEBUG_DUMP_COMMANDS #include "../core/alloc_func.hpp" #endif /* DEBUG_DUMP_COMMANDS */ - #include "table/strings.h" bool _network_reload_cfg; @@ -46,6 +46,29 @@ bool _network_server; ///< network-server is active bool _network_available; ///< is network mode available? bool _network_dedicated; ///< are we a dedicated server? bool _network_advertise; ///< is the server advertising to the master server? +bool _is_network_server; ///< Does this client wants to be a network-server? +NetworkGameInfo _network_game_info; +NetworkPlayerInfo _network_player_info[MAX_PLAYERS]; +NetworkClientInfo _network_client_info[MAX_CLIENT_INFO]; +uint16 _network_own_client_index; +uint16 _redirect_console_to_client; +bool _network_need_advertise; +uint32 _network_last_advertise_frame; +uint8 _network_reconnect; +char *_network_host_list[10]; +char *_network_ban_list[25]; +uint32 _frame_counter_server; // The frame_counter of the server, if in network-mode +uint32 _frame_counter_max; // To where we may go with our clients +uint32 _last_sync_frame; // Used in the server to store the last time a sync packet was sent to clients. +uint32 _broadcast_list[MAX_INTERFACES + 1]; +uint32 _network_server_bind_ip; +uint32 _sync_seed_1, _sync_seed_2; +uint32 _sync_frame; +bool _network_first_time; +uint32 _network_last_host_ip; +bool _network_udp_server; +uint16 _network_udp_broadcast; +uint8 _network_advertise_retries; /* Check whether NETWORK_NUM_LANDSCAPES is still in sync with NUM_LANDSCAPE */ assert_compile((int)NETWORK_NUM_LANDSCAPES == (int)NUM_LANDSCAPE); @@ -337,13 +360,13 @@ void CheckMinPlayers() _min_players_paused = true; DoCommandP(0, 1, 0, NULL, CMD_PAUSE); - NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (not enough players)", NETWORK_SERVER_INDEX); + NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (not enough players)", NETWORK_SERVER_INDEX); } else { if (!_min_players_paused) return; _min_players_paused = false; DoCommandP(0, 0, 0, NULL, CMD_PAUSE); - NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (enough players)", NETWORK_SERVER_INDEX); + NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (enough players)", NETWORK_SERVER_INDEX); } } @@ -664,7 +687,7 @@ void NetworkCloseClient(NetworkTCPSocketHandler *cs) /* When the client was PRE_ACTIVE, the server was in pause mode, so unpause */ if (cs->status == STATUS_PRE_ACTIVE && _settings_client.network.pause_on_join) { DoCommandP(0, 0, 0, NULL, CMD_PAUSE); - NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused", NETWORK_SERVER_INDEX); + NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused", NETWORK_SERVER_INDEX); } cs->Destroy(); diff --git a/src/network/network.h b/src/network/network.h index 0e4653901..1331a6826 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -17,6 +17,7 @@ extern bool _network_server; ///< network-server is active extern bool _network_available; ///< is network mode available? extern bool _network_dedicated; ///< are we a dedicated server? extern bool _network_advertise; ///< is the server advertising to the master server? +extern bool _is_network_server; ///< Does this client wants to be a network-server? #else /* ENABLE_NETWORK */ /* Network function stubs when networking is disabled */ @@ -29,6 +30,7 @@ static inline void NetworkShutDown() {} #define _network_available 0 #define _network_dedicated 0 #define _network_advertise 0 +#define _is_network_server 0 #endif /* ENABLE_NETWORK */ diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 9411a28a4..cd2df7f23 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -7,7 +7,7 @@ #include "../stdafx.h" #include "../debug.h" #include "../openttd.h" -#include "network_data.h" +#include "network_internal.h" #include "core/tcp.h" #include "network_client.h" #include "network_gamelist.h" @@ -938,4 +938,39 @@ NetworkRecvStatus NetworkClient_ReadPackets(NetworkTCPSocketHandler *cs) return res; } +void NetworkClientSendRcon(const char *password, const char *command) +{ + SEND_COMMAND(PACKET_CLIENT_RCON)(password, command); +} + +void NetworkUpdatePlayerName() +{ + NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(_network_own_client_index); + + if (ci == NULL) return; + + /* Don't change the name if it is the same as the old name */ + if (strcmp(ci->client_name, _settings_client.network.player_name) != 0) { + if (!_network_server) { + SEND_COMMAND(PACKET_CLIENT_SET_NAME)(_settings_client.network.player_name); + } else { + if (NetworkFindName(_settings_client.network.player_name)) { + NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, "%s", _settings_client.network.player_name); + ttd_strlcpy(ci->client_name, _settings_client.network.player_name, sizeof(ci->client_name)); + NetworkUpdateClientInfo(NETWORK_SERVER_INDEX); + } + } + } +} + +void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg) +{ + SEND_COMMAND(PACKET_CLIENT_CHAT)(action, type, dest, msg); +} + +void NetworkClientSetPassword() +{ + SEND_COMMAND(PACKET_CLIENT_SET_PASSWORD)(_network_player_info[_local_player].password); +} + #endif /* ENABLE_NETWORK */ diff --git a/src/network/network_data.cpp b/src/network/network_data.cpp index ede255ba9..b24b2e498 100644 --- a/src/network/network_data.cpp +++ b/src/network/network_data.cpp @@ -6,7 +6,7 @@ #include "../stdafx.h" #include "../debug.h" -#include "network_data.h" +#include "network_internal.h" #include "network_client.h" #include "../command_func.h" #include "../callback_table.h" diff --git a/src/network/network_data.h b/src/network/network_data.h deleted file mode 100644 index 2541fac0b..000000000 --- a/src/network/network_data.h +++ /dev/null @@ -1,121 +0,0 @@ -/* $Id$ */ - -/** @file network_data.h Internal functions. */ - -#ifndef NETWORK_DATA_H -#define NETWORK_DATA_H - -#include "../openttd.h" -#include "../console_type.h" -#include "network.h" -#include "network_internal.h" - -// Is the network enabled? -#ifdef ENABLE_NETWORK - -#include "core/os_abstraction.h" -#include "core/core.h" -#include "core/config.h" -#include "core/packet.h" -#include "core/tcp.h" - -#define MAX_TEXT_MSG_LEN 1024 /* long long long long sentences :-) */ - -// The client-info-server-index is always 1 -#define NETWORK_SERVER_INDEX 1 -#define NETWORK_EMPTY_INDEX 0 - -enum MapPacket { - MAP_PACKET_START, - MAP_PACKET_NORMAL, - MAP_PACKET_END, -}; - -enum NetworkErrorCode { - NETWORK_ERROR_GENERAL, // Try to use thisone like never - - // Signals from clients - NETWORK_ERROR_DESYNC, - NETWORK_ERROR_SAVEGAME_FAILED, - NETWORK_ERROR_CONNECTION_LOST, - NETWORK_ERROR_ILLEGAL_PACKET, - NETWORK_ERROR_NEWGRF_MISMATCH, - - // Signals from servers - NETWORK_ERROR_NOT_AUTHORIZED, - NETWORK_ERROR_NOT_EXPECTED, - NETWORK_ERROR_WRONG_REVISION, - NETWORK_ERROR_NAME_IN_USE, - NETWORK_ERROR_WRONG_PASSWORD, - NETWORK_ERROR_PLAYER_MISMATCH, // Happens in CLIENT_COMMAND - NETWORK_ERROR_KICKED, - NETWORK_ERROR_CHEATER, - NETWORK_ERROR_FULL, -}; - -// Actions that can be used for NetworkTextMessage -enum NetworkAction { - NETWORK_ACTION_JOIN, - NETWORK_ACTION_LEAVE, - NETWORK_ACTION_SERVER_MESSAGE, - NETWORK_ACTION_CHAT, - NETWORK_ACTION_CHAT_COMPANY, - NETWORK_ACTION_CHAT_CLIENT, - NETWORK_ACTION_GIVE_MONEY, - NETWORK_ACTION_NAME_CHANGE, -}; - -enum NetworkPasswordType { - NETWORK_GAME_PASSWORD, - NETWORK_COMPANY_PASSWORD, -}; - -enum DestType { - DESTTYPE_BROADCAST, ///< Send message/notice to all players (All) - DESTTYPE_TEAM, ///< Send message/notice to everyone playing the same company (Team) - DESTTYPE_CLIENT, ///< Send message/notice to only a certain player (Private) -}; - -// following externs are instantiated at network.cpp -extern CommandPacket *_local_command_queue; - -// Here we keep track of the clients -// (and the client uses [0] for his own communication) -extern NetworkTCPSocketHandler _clients[MAX_CLIENTS]; - -#define DEREF_CLIENT(i) (&_clients[i]) -// This returns the NetworkClientInfo from a NetworkClientState -#define DEREF_CLIENT_INFO(cs) (&_network_client_info[cs - _clients]) - -// Macros to make life a bit more easier -#define DEF_CLIENT_RECEIVE_COMMAND(type) NetworkRecvStatus NetworkPacketReceive_ ## type ## _command(Packet *p) -#define DEF_CLIENT_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command() -#define DEF_CLIENT_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command -#define DEF_SERVER_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(NetworkTCPSocketHandler *cs, Packet *p) -#define DEF_SERVER_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(NetworkTCPSocketHandler *cs) -#define DEF_SERVER_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command - -#define SEND_COMMAND(type) NetworkPacketSend_ ## type ## _command -#define RECEIVE_COMMAND(type) NetworkPacketReceive_ ## type ## _command - -#define FOR_ALL_CLIENTS(cs) for (cs = _clients; cs != endof(_clients) && cs->IsConnected(); cs++) -#define FOR_ALL_ACTIVE_CLIENT_INFOS(ci) for (ci = _network_client_info; ci != endof(_network_client_info); ci++) if (ci->client_index != NETWORK_EMPTY_INDEX) - -void NetworkExecuteCommand(CommandPacket *cp); -void NetworkAddCommandQueue(NetworkTCPSocketHandler *cs, CommandPacket *cp); - -// from network.c -void NetworkCloseClient(NetworkTCPSocketHandler *cs); -void CDECL NetworkTextMessage(NetworkAction action, ConsoleColour color, bool self_send, const char *name, const char *str, ...); -void NetworkGetClientName(char *clientname, size_t size, const NetworkTCPSocketHandler *cs); -uint NetworkCalculateLag(const NetworkTCPSocketHandler *cs); -byte NetworkGetCurrentLanguageIndex(); -NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index); -NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip); -NetworkTCPSocketHandler *NetworkFindClientStateFromIndex(uint16 client_index); -unsigned long NetworkResolveHost(const char *hostname); -char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last); - -#endif /* ENABLE_NETWORK */ - -#endif /* NETWORK_DATA_H */ diff --git a/src/network/network_func.h b/src/network/network_func.h new file mode 100644 index 000000000..599defb9d --- /dev/null +++ b/src/network/network_func.h @@ -0,0 +1,63 @@ +/* $Id$ */ + +/** @file network_internal.h Variables and function used internally. */ + +#ifndef NETWORK_FUNC_H +#define NETWORK_FUNC_H + +#ifdef ENABLE_NETWORK + +#include "network_type.h" +#include "../console_type.h" + +extern NetworkGameInfo _network_game_info; +extern NetworkPlayerInfo _network_player_info[MAX_PLAYERS]; +extern NetworkClientInfo _network_client_info[MAX_CLIENT_INFO]; + +extern uint16 _network_own_client_index; +extern uint16 _redirect_console_to_client; +extern bool _network_need_advertise; +extern uint32 _network_last_advertise_frame; +extern uint8 _network_reconnect; +extern char *_network_host_list[10]; +extern char *_network_ban_list[25]; + +byte NetworkSpectatorCount(); +void CheckMinPlayers(); +void NetworkUpdatePlayerName(); +bool NetworkCompanyHasPlayers(PlayerID company); +bool NetworkChangeCompanyPassword(byte argc, char *argv[]); +void NetworkReboot(); +void NetworkDisconnect(); +void NetworkGameLoop(); +void NetworkUDPGameLoop(); +void NetworkUDPCloseAll(); +void ParseConnectionString(const char **player, const char **port, char *connection_string); +void NetworkStartDebugLog(const char *hostname, uint16 port); +void NetworkPopulateCompanyInfo(); + +void NetworkUpdateClientInfo(uint16 client_index); +bool NetworkClientConnectGame(const char *host, uint16 port); +void NetworkClientSendRcon(const char *password, const char *command); +void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg); +void NetworkClientSetPassword(); + +/*** Commands ran by the server ***/ +void NetworkServerMonthlyLoop(); +void NetworkServerYearlyLoop(); +void NetworkServerChangeOwner(PlayerID current_player, PlayerID new_player); +void NetworkServerShowStatusToConsole(); +bool NetworkServerStart(); + +NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index); +NetworkClientInfo *NetworkFindClientInfoFromIP(const char *ip); +const char* GetPlayerIP(const NetworkClientInfo *ci); + +void NetworkServerSendRcon(uint16 client_index, ConsoleColour colour_code, const char *string); +void NetworkServerSendError(uint16 client_index, NetworkErrorCode error); +void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const char *msg, uint16 from_index); + +#define FOR_ALL_ACTIVE_CLIENT_INFOS(ci) for (ci = _network_client_info; ci != endof(_network_client_info); ci++) if (ci->client_index != NETWORK_EMPTY_INDEX) + +#endif /* ENABLE_NETWORK */ +#endif /* NETWORK_FUNC_H */ diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index f821c063f..efec52220 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -11,6 +11,7 @@ #include "../debug.h" #include "../newgrf_config.h" #include "../core/alloc_func.hpp" +#include "network_internal.h" #include "core/game.h" #include "network_udp.h" #include "network_gamelist.h" diff --git a/src/network/network_gamelist.h b/src/network/network_gamelist.h index 31ec69171..a7e8f3578 100644 --- a/src/network/network_gamelist.h +++ b/src/network/network_gamelist.h @@ -5,6 +5,8 @@ #ifndef NETWORK_GAMELIST_H #define NETWORK_GAMELIST_H +#include "network_type.h" + /** Structure with information shown in the game list (GUI) */ struct NetworkGameList { NetworkGameInfo info; ///< The game information of this server diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 413a0b530..9125fd2e6 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -9,7 +9,7 @@ #include "network.h" #include "../date_func.h" #include "../fios.h" -#include "network_data.h" +#include "network_internal.h" #include "network_client.h" #include "network_gui.h" #include "network_gamelist.h" @@ -1559,6 +1559,12 @@ void ShowNetworkNeedPassword(NetworkPasswordType npt) ShowQueryString(STR_EMPTY, caption, 20, 180, FindWindowById(WC_NETWORK_STATUS_WINDOW, 0), CS_ALPHANUMERAL); } +// Vars needed for the join-GUI +NetworkJoinStatus _network_join_status; +uint8 _network_join_waiting; +uint16 _network_join_kbytes; +uint16 _network_join_kbytes_total; + struct NetworkJoinStatusWindow : Window { NetworkJoinStatusWindow(const WindowDesc *desc) : Window(desc) { @@ -1640,7 +1646,7 @@ static void SendChat(const char *buf, DestType type, int dest) if (!_network_server) { SEND_COMMAND(PACKET_CLIENT_CHAT)((NetworkAction)(NETWORK_ACTION_CHAT + type), type, dest, buf); } else { - NetworkServer_HandleChat((NetworkAction)(NETWORK_ACTION_CHAT + type), type, dest, buf, NETWORK_SERVER_INDEX); + NetworkServerSendChat((NetworkAction)(NETWORK_ACTION_CHAT + type), type, dest, buf, NETWORK_SERVER_INDEX); } } diff --git a/src/network/network_gui.h b/src/network/network_gui.h index 46cd67826..77276a8fb 100644 --- a/src/network/network_gui.h +++ b/src/network/network_gui.h @@ -5,11 +5,10 @@ #ifndef NETWORK_GUI_H #define NETWORK_GUI_H -#include "../window_type.h" - #ifdef ENABLE_NETWORK -#include "network_data.h" +#include "../window_type.h" +#include "network_type.h" void ShowNetworkNeedPassword(NetworkPasswordType npt); void ShowNetworkGiveMoneyWindow(PlayerID player); // PlayerID diff --git a/src/network/network_internal.h b/src/network/network_internal.h index d38e8bcc0..3ebf04f72 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -7,10 +7,13 @@ #ifdef ENABLE_NETWORK -#include "../player_type.h" -#include "../economy_type.h" +#include "network.h" +#include "network_func.h" +#include "core/os_abstraction.h" +#include "core/core.h" #include "core/config.h" -#include "core/game.h" +#include "core/packet.h" +#include "core/tcp.h" /** * If this line is enable, every frame will have a sync test @@ -29,50 +32,14 @@ */ //#define NETWORK_SEND_DOUBLE_SEED +#define MAX_TEXT_MSG_LEN 1024 /* long long long long sentences :-) */ -enum { - /** - * How many clients can we have? Like.. MAX_PLAYERS - 1 is the amount of - * players that can really play.. so.. a max of 4 spectators.. gives us.. - * MAX_PLAYERS + 3 - */ - MAX_CLIENTS = MAX_PLAYERS + 3, - - /** Do not change this next line. It should _ALWAYS_ be MAX_CLIENTS + 1 */ - MAX_CLIENT_INFO = MAX_CLIENTS + 1, - - /** Maximum number of internet interfaces supported. */ - MAX_INTERFACES = 9, - - /** How many vehicle/station types we put over the network */ - NETWORK_VEHICLE_TYPES = 5, - NETWORK_STATION_TYPES = 5, +enum MapPacket { + MAP_PACKET_START, + MAP_PACKET_NORMAL, + MAP_PACKET_END, }; -struct NetworkPlayerInfo { - char company_name[NETWORK_NAME_LENGTH]; ///< Company name - char password[NETWORK_PASSWORD_LENGTH]; ///< The password for the player - Year inaugurated_year; ///< What year the company started in - Money company_value; ///< The company value - Money money; ///< The amount of money the company has - Money income; ///< How much did the company earned last year - uint16 performance; ///< What was his performance last month? - bool use_password; ///< Is there a password - uint16 num_vehicle[NETWORK_VEHICLE_TYPES]; ///< How many vehicles are there of this type? - uint16 num_station[NETWORK_STATION_TYPES]; ///< How many stations are there of this type? - char players[NETWORK_PLAYERS_LENGTH]; ///< The players that control this company (Name1, name2, ..) - uint16 months_empty; ///< How many months the company is empty -}; - -struct NetworkClientInfo { - uint16 client_index; ///< Index of the client (same as ClientState->index) - char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< Name of the client - byte client_lang; ///< The language of the client - PlayerID client_playas; ///< As which player is this client playing (PlayerID) - uint32 client_ip; ///< IP-address of the client (so he can be banned) - Date join_date; ///< Gamedate the player has joined - char unique_id[NETWORK_UNIQUE_ID_LENGTH]; ///< Every play sends an unique id so we can indentify him -}; enum NetworkJoinStatus { NETWORK_JOIN_STATUS_CONNECTING, @@ -126,70 +93,83 @@ enum NetworkLanguage { NETLANG_COUNT }; -VARDEF NetworkGameInfo _network_game_info; -VARDEF NetworkPlayerInfo _network_player_info[MAX_PLAYERS]; -VARDEF NetworkClientInfo _network_client_info[MAX_CLIENT_INFO]; +#define VARDEF extern -VARDEF uint16 _network_own_client_index; +extern NetworkGameInfo _network_game_info; +extern NetworkPlayerInfo _network_player_info[MAX_PLAYERS]; -VARDEF uint32 _frame_counter_server; // The frame_counter of the server, if in network-mode -VARDEF uint32 _frame_counter_max; // To where we may go with our clients +extern uint32 _frame_counter_server; // The frame_counter of the server, if in network-mode +extern uint32 _frame_counter_max; // To where we may go with our clients -VARDEF uint32 _last_sync_frame; // Used in the server to store the last time a sync packet was sent to clients. +extern uint32 _last_sync_frame; // Used in the server to store the last time a sync packet was sent to clients. // networking settings -VARDEF uint32 _broadcast_list[MAX_INTERFACES + 1]; +extern uint32 _broadcast_list[MAX_INTERFACES + 1]; -VARDEF uint32 _network_server_bind_ip; -VARDEF bool _is_network_server; // Does this client wants to be a network-server? +extern uint32 _network_server_bind_ip; -VARDEF uint16 _redirect_console_to_client; - -VARDEF uint32 _sync_seed_1, _sync_seed_2; -VARDEF uint32 _sync_frame; -VARDEF bool _network_first_time; +extern uint32 _sync_seed_1, _sync_seed_2; +extern uint32 _sync_frame; +extern bool _network_first_time; // Vars needed for the join-GUI -VARDEF NetworkJoinStatus _network_join_status; -VARDEF uint8 _network_join_waiting; -VARDEF uint16 _network_join_kbytes; -VARDEF uint16 _network_join_kbytes_total; +extern NetworkJoinStatus _network_join_status; +extern uint8 _network_join_waiting; +extern uint16 _network_join_kbytes; +extern uint16 _network_join_kbytes_total; -VARDEF uint32 _network_last_host_ip; -VARDEF uint8 _network_reconnect; +extern uint32 _network_last_host_ip; +extern uint8 _network_reconnect; -VARDEF bool _network_udp_server; -VARDEF uint16 _network_udp_broadcast; +extern bool _network_udp_server; +extern uint16 _network_udp_broadcast; -VARDEF bool _network_need_advertise; -VARDEF uint32 _network_last_advertise_frame; -VARDEF uint8 _network_advertise_retries; +extern uint8 _network_advertise_retries; -void NetworkTCPQueryServer(const char* host, unsigned short port); +// following externs are instantiated at network.cpp +extern CommandPacket *_local_command_queue; -byte NetworkSpectatorCount(); +// Here we keep track of the clients +// (and the client uses [0] for his own communication) +extern NetworkTCPSocketHandler _clients[MAX_CLIENTS]; -VARDEF char *_network_host_list[10]; -VARDEF char *_network_ban_list[25]; +void NetworkTCPQueryServer(const char* host, unsigned short port); -void ParseConnectionString(const char **player, const char **port, char *connection_string); -void NetworkUpdateClientInfo(uint16 client_index); void NetworkAddServer(const char *b); void NetworkRebuildHostList(); -bool NetworkChangeCompanyPassword(byte argc, char *argv[]); -void NetworkPopulateCompanyInfo(); void UpdateNetworkGameWindow(bool unselect); -void CheckMinPlayers(); -void NetworkStartDebugLog(const char *hostname, uint16 port); - -void NetworkUDPCloseAll(); -void NetworkGameLoop(); -void NetworkUDPGameLoop(); -bool NetworkServerStart(); -bool NetworkClientConnectGame(const char *host, uint16 port); -void NetworkReboot(); -void NetworkDisconnect(); bool IsNetworkCompatibleVersion(const char *version); +void NetworkExecuteCommand(CommandPacket *cp); +void NetworkAddCommandQueue(NetworkTCPSocketHandler *cs, CommandPacket *cp); + +// from network.c +void NetworkCloseClient(NetworkTCPSocketHandler *cs); +void CDECL NetworkTextMessage(NetworkAction action, ConsoleColour color, bool self_send, const char *name, const char *str, ...); +void NetworkGetClientName(char *clientname, size_t size, const NetworkTCPSocketHandler *cs); +uint NetworkCalculateLag(const NetworkTCPSocketHandler *cs); +byte NetworkGetCurrentLanguageIndex(); +NetworkTCPSocketHandler *NetworkFindClientStateFromIndex(uint16 client_index); +unsigned long NetworkResolveHost(const char *hostname); +char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last); +bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH]); + +#define DEREF_CLIENT(i) (&_clients[i]) +// This returns the NetworkClientInfo from a NetworkClientState +#define DEREF_CLIENT_INFO(cs) (&_network_client_info[cs - _clients]) + +// Macros to make life a bit more easier +#define DEF_CLIENT_RECEIVE_COMMAND(type) NetworkRecvStatus NetworkPacketReceive_ ## type ## _command(Packet *p) +#define DEF_CLIENT_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command() +#define DEF_CLIENT_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command +#define DEF_SERVER_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(NetworkTCPSocketHandler *cs, Packet *p) +#define DEF_SERVER_SEND_COMMAND(type) void NetworkPacketSend_ ## type ## _command(NetworkTCPSocketHandler *cs) +#define DEF_SERVER_SEND_COMMAND_PARAM(type) void NetworkPacketSend_ ## type ## _command + +#define SEND_COMMAND(type) NetworkPacketSend_ ## type ## _command +#define RECEIVE_COMMAND(type) NetworkPacketReceive_ ## type ## _command + +#define FOR_ALL_CLIENTS(cs) for (cs = _clients; cs != endof(_clients) && cs->IsConnected(); cs++) + #endif /* ENABLE_NETWORK */ #endif /* NETWORK_INTERNAL_H */ diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 7052ff887..3b7da8909 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -8,7 +8,7 @@ #include "../openttd.h" // XXX StringID #include "../debug.h" #include "../strings_func.h" -#include "network_data.h" +#include "network_internal.h" #include "core/tcp.h" #include "../vehicle_base.h" #include "../vehicle_func.h" @@ -804,7 +804,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK) /* Now pause the game till the client is in sync */ DoCommandP(0, 1, 0, NULL, CMD_PAUSE); - NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (incoming client)", NETWORK_SERVER_INDEX); + NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (incoming client)", NETWORK_SERVER_INDEX); } } else { // Wrong status for this packet, give a warning to client, and close connection @@ -1023,7 +1023,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK) if (_settings_client.network.pause_on_join) { DoCommandP(0, 0, 0, NULL, CMD_PAUSE); - NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (client connected)", NETWORK_SERVER_INDEX); + NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (client connected)", NETWORK_SERVER_INDEX); } CheckMinPlayers(); @@ -1040,7 +1040,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK) -void NetworkServer_HandleChat(NetworkAction action, DestType desttype, int dest, const char *msg, uint16 from_index) +void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, uint16 from_index) { NetworkTCPSocketHandler *cs; const NetworkClientInfo *ci, *ci_own, *ci_to; @@ -1146,7 +1146,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT) p->Recv_string(msg, MAX_TEXT_MSG_LEN); - NetworkServer_HandleChat(action, desttype, dest, msg, cs->index); + NetworkServerSendChat(action, desttype, dest, msg, cs->index); } DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD) @@ -1582,4 +1582,82 @@ void NetworkServerMonthlyLoop() NetworkAutoCleanCompanies(); } +void NetworkServerChangeOwner(PlayerID current_player, PlayerID new_player) +{ + /* The server has to handle all administrative issues, for example + * updating and notifying all clients of what has happened */ + NetworkTCPSocketHandler *cs; + NetworkClientInfo *ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX); + + /* The server has just changed from player */ + if (current_player == ci->client_playas) { + ci->client_playas = new_player; + NetworkUpdateClientInfo(NETWORK_SERVER_INDEX); + } + + /* Find all clients that were in control of this company, and mark them as new_player */ + FOR_ALL_CLIENTS(cs) { + ci = DEREF_CLIENT_INFO(cs); + if (current_player == ci->client_playas) { + ci->client_playas = new_player; + NetworkUpdateClientInfo(ci->client_index); + } + } +} + +const char* GetPlayerIP(const NetworkClientInfo* ci) +{ + struct in_addr addr; + + addr.s_addr = ci->client_ip; + return inet_ntoa(addr); +} + +void NetworkServerShowStatusToConsole() +{ + static const char* const stat_str[] = { + "inactive", + "authorizing", + "authorized", + "waiting", + "loading map", + "map done", + "ready", + "active" + }; + + NetworkTCPSocketHandler *cs; + FOR_ALL_CLIENTS(cs) { + int lag = NetworkCalculateLag(cs); + const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs); + const char* status; + + status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown"); + IConsolePrintF(CC_INFO, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s unique-id: '%s'", + cs->index, ci->client_name, status, lag, + ci->client_playas + (IsValidPlayer(ci->client_playas) ? 1 : 0), + GetPlayerIP(ci), ci->unique_id); + } +} + +void NetworkServerSendRcon(uint16 client_index, ConsoleColour colour_code, const char *string) +{ + SEND_COMMAND(PACKET_SERVER_RCON)(NetworkFindClientStateFromIndex(client_index), colour_code, string); +} + +void NetworkServerSendError(uint16 client_index, NetworkErrorCode error) +{ + SEND_COMMAND(PACKET_SERVER_ERROR)(NetworkFindClientStateFromIndex(client_index), error); +} + +bool NetworkCompanyHasPlayers(PlayerID company) +{ + const NetworkTCPSocketHandler *cs; + const NetworkClientInfo *ci; + FOR_ALL_CLIENTS(cs) { + ci = DEREF_CLIENT_INFO(cs); + if (ci->client_playas == company) return true; + } + return false; +} #endif /* ENABLE_NETWORK */ diff --git a/src/network/network_server.h b/src/network/network_server.h index 07f9cf29a..3b5b02fef 100644 --- a/src/network/network_server.h +++ b/src/network/network_server.h @@ -14,21 +14,8 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN); DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME); DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkTCPSocketHandler *cs, uint16 color, const char *command); -bool NetworkFindName(char new_name[NETWORK_CLIENT_NAME_LENGTH]); -void NetworkServer_HandleChat(NetworkAction action, DestType type, int dest, const char *msg, uint16 from_index); - bool NetworkServer_ReadPackets(NetworkTCPSocketHandler *cs); void NetworkServer_Tick(bool send_frame); -void NetworkServerMonthlyLoop(); -void NetworkServerYearlyLoop(); - -static inline const char* GetPlayerIP(const NetworkClientInfo* ci) -{ - struct in_addr addr; - - addr.s_addr = ci->client_ip; - return inet_ntoa(addr); -} #else /* ENABLE_NETWORK */ /* Network function stubs when networking is disabled */ diff --git a/src/network/network_type.h b/src/network/network_type.h new file mode 100644 index 000000000..17bf382dc --- /dev/null +++ b/src/network/network_type.h @@ -0,0 +1,108 @@ +/* $Id$ */ + +/** @file network_internal.h Variables and function used internally. */ + +#ifndef NETWORK_TYPE_H +#define NETWORK_TYPE_H + +#ifdef ENABLE_NETWORK + +#include "../player_type.h" +#include "../economy_type.h" +#include "core/config.h" +#include "core/game.h" + +enum { + /** + * How many clients can we have? Like.. MAX_PLAYERS - 1 is the amount of + * players that can really play.. so.. a max of 4 spectators.. gives us.. + * MAX_PLAYERS + 3 + */ + MAX_CLIENTS = MAX_PLAYERS + 3, + + /** Do not change this next line. It should _ALWAYS_ be MAX_CLIENTS + 1 */ + MAX_CLIENT_INFO = MAX_CLIENTS + 1, + + /** Maximum number of internet interfaces supported. */ + MAX_INTERFACES = 9, + + /** How many vehicle/station types we put over the network */ + NETWORK_VEHICLE_TYPES = 5, + NETWORK_STATION_TYPES = 5, + + NETWORK_SERVER_INDEX = 1, + NETWORK_EMPTY_INDEX = 0, +}; + +struct NetworkPlayerInfo { + char company_name[NETWORK_NAME_LENGTH]; ///< Company name + char password[NETWORK_PASSWORD_LENGTH]; ///< The password for the player + Year inaugurated_year; ///< What year the company started in + Money company_value; ///< The company value + Money money; ///< The amount of money the company has + Money income; ///< How much did the company earned last year + uint16 performance; ///< What was his performance last month? + bool use_password; ///< Is there a password + uint16 num_vehicle[NETWORK_VEHICLE_TYPES]; ///< How many vehicles are there of this type? + uint16 num_station[NETWORK_STATION_TYPES]; ///< How many stations are there of this type? + char players[NETWORK_PLAYERS_LENGTH]; ///< The players that control this company (Name1, name2, ..) + uint16 months_empty; ///< How many months the company is empty +}; + +struct NetworkClientInfo { + uint16 client_index; ///< Index of the client (same as ClientState->index) + char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< Name of the client + byte client_lang; ///< The language of the client + PlayerID client_playas; ///< As which player is this client playing (PlayerID) + uint32 client_ip; ///< IP-address of the client (so he can be banned) + Date join_date; ///< Gamedate the player has joined + char unique_id[NETWORK_UNIQUE_ID_LENGTH]; ///< Every play sends an unique id so we can indentify him +}; + +enum NetworkPasswordType { + NETWORK_GAME_PASSWORD, + NETWORK_COMPANY_PASSWORD, +}; + +enum DestType { + DESTTYPE_BROADCAST, ///< Send message/notice to all players (All) + DESTTYPE_TEAM, ///< Send message/notice to everyone playing the same company (Team) + DESTTYPE_CLIENT, ///< Send message/notice to only a certain player (Private) +}; + +/** Actions that can be used for NetworkTextMessage */ +enum NetworkAction { + NETWORK_ACTION_JOIN, + NETWORK_ACTION_LEAVE, + NETWORK_ACTION_SERVER_MESSAGE, + NETWORK_ACTION_CHAT, + NETWORK_ACTION_CHAT_COMPANY, + NETWORK_ACTION_CHAT_CLIENT, + NETWORK_ACTION_GIVE_MONEY, + NETWORK_ACTION_NAME_CHANGE, +}; + +enum NetworkErrorCode { + NETWORK_ERROR_GENERAL, // Try to use this one like never + + /* Signals from clients */ + NETWORK_ERROR_DESYNC, + NETWORK_ERROR_SAVEGAME_FAILED, + NETWORK_ERROR_CONNECTION_LOST, + NETWORK_ERROR_ILLEGAL_PACKET, + NETWORK_ERROR_NEWGRF_MISMATCH, + + /* Signals from servers */ + NETWORK_ERROR_NOT_AUTHORIZED, + NETWORK_ERROR_NOT_EXPECTED, + NETWORK_ERROR_WRONG_REVISION, + NETWORK_ERROR_NAME_IN_USE, + NETWORK_ERROR_WRONG_PASSWORD, + NETWORK_ERROR_PLAYER_MISMATCH, // Happens in CLIENT_COMMAND + NETWORK_ERROR_KICKED, + NETWORK_ERROR_CHEATER, + NETWORK_ERROR_FULL, +}; + +#endif /* ENABLE_NETWORK */ +#endif /* NETWORK_TYPE_H */ diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index ef533356b..33c9d108f 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -11,11 +11,11 @@ #include "../stdafx.h" #include "../debug.h" -#include "network_data.h" #include "../date_func.h" #include "../map_func.h" #include "network_gamelist.h" #include "network_udp.h" +#include "network_internal.h" #include "../variables.h" #include "../newgrf_config.h" #include "../core/endian_func.hpp" |