OpenTTD Source  20241121-master-g67a0fccfad
network_command.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "../stdafx.h"
11 #include "network_admin.h"
12 #include "network_client.h"
13 #include "network_server.h"
14 #include "../command_func.h"
15 #include "../company_func.h"
16 #include "../settings_type.h"
17 #include "../airport_cmd.h"
18 #include "../aircraft_cmd.h"
19 #include "../autoreplace_cmd.h"
20 #include "../company_cmd.h"
21 #include "../depot_cmd.h"
22 #include "../dock_cmd.h"
23 #include "../economy_cmd.h"
24 #include "../engine_cmd.h"
25 #include "../error_func.h"
26 #include "../goal_cmd.h"
27 #include "../group_cmd.h"
28 #include "../industry_cmd.h"
29 #include "../landscape_cmd.h"
30 #include "../league_cmd.h"
31 #include "../misc_cmd.h"
32 #include "../news_cmd.h"
33 #include "../object_cmd.h"
34 #include "../order_cmd.h"
35 #include "../rail_cmd.h"
36 #include "../road_cmd.h"
37 #include "../roadveh_cmd.h"
38 #include "../settings_cmd.h"
39 #include "../signs_cmd.h"
40 #include "../station_cmd.h"
41 #include "../story_cmd.h"
42 #include "../subsidy_cmd.h"
43 #include "../terraform_cmd.h"
44 #include "../timetable_cmd.h"
45 #include "../town_cmd.h"
46 #include "../train_cmd.h"
47 #include "../tree_cmd.h"
48 #include "../tunnelbridge_cmd.h"
49 #include "../vehicle_cmd.h"
50 #include "../viewport_cmd.h"
51 #include "../water_cmd.h"
52 #include "../waypoint_cmd.h"
53 #include "../script/script_cmd.h"
54 
55 #include "../safeguards.h"
56 
58 static constexpr auto _callback_tuple = std::make_tuple(
59  (CommandCallback *)nullptr, // Make sure this is actually a pointer-to-function.
61  &CcBuildAirport,
63  &CcPlaySound_CONSTRUCTION_WATER,
64  &CcBuildDocks,
65  &CcFoundTown,
68  &CcBuildWagon,
69  &CcRoadDepot,
70  &CcRailDepot,
71  &CcPlaceSign,
72  &CcPlaySound_EXPLOSION,
73  &CcPlaySound_CONSTRUCTION_OTHER,
74  &CcPlaySound_CONSTRUCTION_RAIL,
75  &CcStation,
76  &CcTerraform,
77  &CcAI,
80  &CcFoundRandomTown,
81  &CcRoadStop,
84  &CcGame,
86 );
87 
88 #ifdef SILENCE_GCC_FUNCTION_POINTER_CAST
89 /*
90  * We cast specialized function pointers to a generic one, but don't use the
91  * converted value to call the function, which is safe, except that GCC
92  * helpfully thinks it is not.
93  *
94  * "Any pointer to function can be converted to a pointer to a different function type.
95  * Calling the function through a pointer to a different function type is undefined,
96  * but converting such pointer back to pointer to the original function type yields
97  * the pointer to the original function." */
98 # pragma GCC diagnostic push
99 # pragma GCC diagnostic ignored "-Wcast-function-type"
100 #endif
101 
102 /* Helpers to generate the callback table from the callback list. */
103 
104 inline constexpr size_t _callback_tuple_size = std::tuple_size_v<decltype(_callback_tuple)>;
105 
106 template <size_t... i>
107 inline auto MakeCallbackTable(std::index_sequence<i...>) noexcept
108 {
109  return std::array<CommandCallback *, sizeof...(i)>{{ reinterpret_cast<CommandCallback *>(reinterpret_cast<void(*)()>(std::get<i>(_callback_tuple)))... }}; // MingW64 fails linking when casting a pointer to its own type. To work around, cast it to some other type first.
110 }
111 
113 static auto _callback_table = MakeCallbackTable(std::make_index_sequence<_callback_tuple_size>{});
114 
115 template <typename T> struct CallbackArgsHelper;
116 template <typename... Targs>
117 struct CallbackArgsHelper<void(*const)(Commands, const CommandCost &, Targs...)> {
118  using Args = std::tuple<std::decay_t<Targs>...>;
119 };
120 
121 
122 /* Helpers to generate the command dispatch table from the command traits. */
123 
124 template <Commands Tcmd> static CommandDataBuffer SanitizeCmdStrings(const CommandDataBuffer &data);
125 template <Commands Tcmd, size_t cb> static void UnpackNetworkCommand(const CommandPacket &cp);
126 template <Commands Tcmd> static void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id);
127 using UnpackNetworkCommandProc = void (*)(const CommandPacket &);
128 using UnpackDispatchT = std::array<UnpackNetworkCommandProc, _callback_tuple_size>;
130  CommandDataBuffer(*Sanitize)(const CommandDataBuffer &);
131  void (*ReplaceClientId)(CommandPacket &, ClientID);
132  UnpackDispatchT Unpack;
133 };
134 
135 template <Commands Tcmd, size_t Tcb>
136 constexpr UnpackNetworkCommandProc MakeUnpackNetworkCommandCallback() noexcept
137 {
138  /* Check if the callback matches with the command arguments. If not, don't generate an Unpack proc. */
139  using Tcallback = std::tuple_element_t<Tcb, decltype(_callback_tuple)>;
140  if constexpr (std::is_same_v<Tcallback, CommandCallback * const> || // Callback type is CommandCallback.
141  std::is_same_v<Tcallback, CommandCallbackData * const> || // Callback type is CommandCallbackData.
142  std::is_same_v<typename CommandTraits<Tcmd>::CbArgs, typename CallbackArgsHelper<Tcallback>::Args> || // Callback proc takes all command return values and parameters.
143  (!std::is_void_v<typename CommandTraits<Tcmd>::RetTypes> && std::is_same_v<typename CallbackArgsHelper<typename CommandTraits<Tcmd>::RetCallbackProc const>::Args, typename CallbackArgsHelper<Tcallback>::Args>)) { // Callback return is more than CommandCost and the proc takes all return values.
144  return &UnpackNetworkCommand<Tcmd, Tcb>;
145  } else {
146  return nullptr;
147  }
148 }
149 
150 template <Commands Tcmd, size_t... i>
151 constexpr UnpackDispatchT MakeUnpackNetworkCommand(std::index_sequence<i...>) noexcept
152 {
153  return UnpackDispatchT{{ MakeUnpackNetworkCommandCallback<Tcmd, i>()...}};
154 }
155 
156 template <typename T, T... i, size_t... j>
157 inline constexpr auto MakeDispatchTable(std::integer_sequence<T, i...>, std::index_sequence<j...>) noexcept
158 {
159  return std::array<CommandDispatch, sizeof...(i)>{{ { &SanitizeCmdStrings<static_cast<Commands>(i)>, &NetworkReplaceCommandClientId<static_cast<Commands>(i)>, MakeUnpackNetworkCommand<static_cast<Commands>(i)>(std::make_index_sequence<_callback_tuple_size>{}) }... }};
160 }
162 static constexpr auto _cmd_dispatch = MakeDispatchTable(std::make_integer_sequence<std::underlying_type_t<Commands>, CMD_END>{}, std::make_index_sequence<_callback_tuple_size>{});
163 
164 #ifdef SILENCE_GCC_FUNCTION_POINTER_CAST
165 # pragma GCC diagnostic pop
166 #endif
167 
172 
173 
179 static size_t FindCallbackIndex(CommandCallback *callback)
180 {
181  if (auto it = std::find(std::cbegin(_callback_table), std::cend(_callback_table), callback); it != std::cend(_callback_table)) {
182  return static_cast<size_t>(std::distance(std::cbegin(_callback_table), it));
183  }
184 
185  return std::numeric_limits<size_t>::max();
186 }
187 
196 void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, const CommandDataBuffer &cmd_data)
197 {
198  CommandPacket c;
199  c.company = company;
200  c.cmd = cmd;
201  c.err_msg = err_message;
202  c.callback = callback;
203  c.data = cmd_data;
204 
205  if (_network_server) {
206  /* If we are the server, we queue the command in our 'special' queue.
207  * In theory, we could execute the command right away, but then the
208  * client on the server can do everything 1 tick faster than others.
209  * So to keep the game fair, we delay the command with 1 tick
210  * which gives about the same speed as most clients.
211  */
212  c.frame = _frame_counter_max + 1;
213  c.my_cmd = true;
214 
215  _local_wait_queue.push_back(c);
216  return;
217  }
218 
219  c.frame = 0; // The client can't tell which frame, so just make it 0
220 
221  /* Clients send their command to the server and forget all about the packet */
223 }
224 
234 void NetworkSyncCommandQueue(NetworkClientSocket *cs)
235 {
236  for (auto &p : _local_execution_queue) {
237  CommandPacket &c = cs->outgoing_queue.emplace_back(p);
238  c.callback = nullptr;
239  }
240 }
241 
246 {
247  assert(IsLocalCompany());
248 
250 
251  auto cp = queue.begin();
252  for (; cp != queue.end(); cp++) {
253  /* The queue is always in order, which means
254  * that the first element will be executed first. */
255  if (_frame_counter < cp->frame) break;
256 
257  if (_frame_counter > cp->frame) {
258  /* If we reach here, it means for whatever reason, we've already executed
259  * past the command we need to execute. */
260  FatalError("[net] Trying to execute a packet in the past!");
261  }
262 
263  /* We can execute this command */
264  _current_company = cp->company;
265  size_t cb_index = FindCallbackIndex(cp->callback);
266  assert(cb_index < _callback_tuple_size);
267  assert(_cmd_dispatch[cp->cmd].Unpack[cb_index] != nullptr);
268  _cmd_dispatch[cp->cmd].Unpack[cb_index](*cp);
269  }
270  queue.erase(queue.begin(), cp);
271 
272  /* Local company may have changed, so we should not restore the old value */
274 }
275 
280 {
281  _local_wait_queue.clear();
282  _local_execution_queue.clear();
283 }
284 
290 static void DistributeCommandPacket(CommandPacket &cp, const NetworkClientSocket *owner)
291 {
292  CommandCallback *callback = cp.callback;
293  cp.frame = _frame_counter_max + 1;
294 
295  for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
296  if (cs->status >= NetworkClientSocket::STATUS_MAP) {
297  /* Callbacks are only send back to the client who sent them in the
298  * first place. This filters that out. */
299  cp.callback = (cs != owner) ? nullptr : callback;
300  cp.my_cmd = (cs == owner);
301  cs->outgoing_queue.push_back(cp);
302  }
303  }
304 
305  cp.callback = (nullptr != owner) ? nullptr : callback;
306  cp.my_cmd = (nullptr == owner);
307  _local_execution_queue.push_back(cp);
308 }
309 
315 static void DistributeQueue(CommandQueue &queue, const NetworkClientSocket *owner)
316 {
317 #ifdef DEBUG_DUMP_COMMANDS
318  /* When replaying we do not want this limitation. */
319  int to_go = UINT16_MAX;
320 #else
322  if (owner == nullptr) {
323  /* This is the server, use the commands_per_frame_server setting if higher */
324  to_go = std::max<int>(to_go, _settings_client.network.commands_per_frame_server);
325  }
326 #endif
327 
328  /* Not technically the most performant way, but consider clients rarely click more than once per tick. */
329  for (auto cp = queue.begin(); cp != queue.end(); /* removing some items */) {
330  /* Do not distribute commands when paused and the command is not allowed while paused. */
332  ++cp;
333  continue;
334  }
335 
336  /* Limit the number of commands per client per tick. */
337  if (--to_go < 0) break;
338 
339  DistributeCommandPacket(*cp, owner);
340  NetworkAdminCmdLogging(owner, *cp);
341  cp = queue.erase(cp);
342  }
343 }
344 
347 {
348  /* First send the server's commands. */
350 
351  /* Then send the queues of the others. */
352  for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
353  DistributeQueue(cs->incoming_queue, cs);
354  }
355 }
356 
364 {
365  cp.company = (CompanyID)p.Recv_uint8();
366  cp.cmd = static_cast<Commands>(p.Recv_uint16());
367  if (!IsValidCommand(cp.cmd)) return "invalid command";
368  if (GetCommandFlags(cp.cmd) & CMD_OFFLINE) return "single-player only command";
369  cp.err_msg = p.Recv_uint16();
370  cp.data = _cmd_dispatch[cp.cmd].Sanitize(p.Recv_buffer());
371 
372  uint8_t callback = p.Recv_uint8();
373  if (callback >= _callback_table.size() || _cmd_dispatch[cp.cmd].Unpack[callback] == nullptr) return "invalid callback";
374 
375  cp.callback = _callback_table[callback];
376  return nullptr;
377 }
378 
385 {
386  p.Send_uint8(cp.company);
387  p.Send_uint16(cp.cmd);
388  p.Send_uint16(cp.err_msg);
389  p.Send_buffer(cp.data);
390 
391  size_t callback = FindCallbackIndex(cp.callback);
392  if (callback > UINT8_MAX || _cmd_dispatch[cp.cmd].Unpack[callback] == nullptr) {
393  Debug(net, 0, "Unknown callback for command; no callback sent (command: {})", cp.cmd);
394  callback = 0; // _callback_table[0] == nullptr
395  }
396  p.Send_uint8 ((uint8_t)callback);
397 }
398 
400 template <class T>
401 static inline void SetClientIdHelper(T &data, [[maybe_unused]] ClientID client_id)
402 {
403  if constexpr (std::is_same_v<ClientID, T>) {
404  data = client_id;
405  }
406 }
407 
409 template<class Ttuple, size_t... Tindices>
410 static inline void SetClientIds(Ttuple &values, ClientID client_id, std::index_sequence<Tindices...>)
411 {
412  ((SetClientIdHelper(std::get<Tindices>(values), client_id)), ...);
413 }
414 
415 template <Commands Tcmd>
417 {
418  /* Unpack command parameters. */
419  auto params = EndianBufferReader::ToValue<typename CommandTraits<Tcmd>::Args>(cp.data);
420 
421  /* Insert client id. */
422  SetClientIds(params, client_id, std::make_index_sequence<std::tuple_size_v<decltype(params)>>{});
423 
424  /* Repack command parameters. */
426 }
427 
434 {
435  _cmd_dispatch[cp.cmd].ReplaceClientId(cp, client_id);
436 }
437 
438 
440 template <class T>
441 static inline void SanitizeSingleStringHelper([[maybe_unused]] CommandFlags cmd_flags, T &data)
442 {
443  if constexpr (std::is_same_v<std::string, T>) {
445  }
446 }
447 
449 template<class Ttuple, size_t... Tindices>
450 static inline void SanitizeStringsHelper(CommandFlags cmd_flags, Ttuple &values, std::index_sequence<Tindices...>)
451 {
452  ((SanitizeSingleStringHelper(cmd_flags, std::get<Tindices>(values))), ...);
453 }
454 
461 template <Commands Tcmd>
463 {
464  auto args = EndianBufferReader::ToValue<typename CommandTraits<Tcmd>::Args>(data);
465  SanitizeStringsHelper(CommandTraits<Tcmd>::flags, args, std::make_index_sequence<std::tuple_size_v<typename CommandTraits<Tcmd>::Args>>{});
467 }
468 
475 template <Commands Tcmd, size_t Tcb>
477 {
478  auto args = EndianBufferReader::ToValue<typename CommandTraits<Tcmd>::Args>(cp.data);
479  Command<Tcmd>::PostFromNet(cp.err_msg, std::get<Tcb>(_callback_tuple), cp.my_cmd, args);
480 }
void CcAI(Commands cmd, const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data)
DoCommand callback function for all commands executed by AIs.
void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, uint8_t)
Callback executed after a build Bridge CMD has been called.
Definition: bridge_gui.cpp:57
static ClientNetworkGameSocketHandler * my_client
This is us!
static NetworkRecvStatus SendCommand(const CommandPacket &cp)
Send a command to the server.
Common return value for all commands.
Definition: command_type.h:23
Endian-aware buffer adapter that always writes values in little endian order.
CommandQueue incoming_queue
The command-queue awaiting handling.
Definition: tcp_game.h:489
const char * ReceiveCommand(Packet &p, CommandPacket &cp)
Receives a command from the network.
void SendCommand(Packet &p, const CommandPacket &cp)
Sends a command over the network.
CommandFlags GetCommandFlags(Commands cmd)
This function mask the parameter with CMD_ID_MASK and returns the flags which belongs to the given co...
Definition: command.cpp:118
bool IsCommandAllowedWhilePaused(Commands cmd)
Returns whether the command is allowed while the game is paused.
Definition: command.cpp:144
bool IsValidCommand(Commands cmd)
This function range-checks a cmd.
Definition: command.cpp:106
void CommandCallback(Commands cmd, const CommandCost &result, TileIndex tile)
Define a callback function for the client, after the command is finished.
Definition: command_type.h:484
std::vector< uint8_t > CommandDataBuffer
Storage buffer for serialized command data.
Definition: command_type.h:470
Commands
List of commands.
Definition: command_type.h:187
@ CMD_END
Must ALWAYS be on the end of this list!! (period)
Definition: command_type.h:366
CommandFlags
Command flags for the command table _command_proc_table.
Definition: command_type.h:396
@ CMD_STR_CTRL
the command's string may contain control strings
Definition: command_type.h:406
@ CMD_OFFLINE
the command cannot be executed in a multiplayer game; single-player only
Definition: command_type.h:399
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:52
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:53
bool IsLocalCompany()
Is the current company the local company?
Definition: company_func.h:47
Owner
Enum for all companies/owners.
Definition: company_type.h:18
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
void CcCloneVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id)
This is the Callback method after the cloning attempt of a vehicle.
Definition: depot_gui.cpp:123
constexpr debug_inline bool HasFlag(const T x, const T y)
Checks if a value in a bitset enum is set.
Definition: enum_type.hpp:58
void CcGame(Commands cmd, const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data)
DoCommand callback function for all commands executed by Game Scripts.
PauseMode _pause_mode
The current pause mode.
Definition: gfx.cpp:50
void CcCreateGroup(Commands cmd, const CommandCost &result, GroupID new_group, VehicleType vt, GroupID parent_group)
Opens a 'Rename group' window for newly created group.
Definition: group_gui.cpp:1227
void CcAddVehicleNewGroup(Commands cmd, const CommandCost &result, GroupID new_group, GroupID, VehicleID veh_id, bool, const VehicleListIdentifier &)
Open rename window after adding a vehicle to a new group via drag and drop.
Definition: group_gui.cpp:1240
void CcBuildIndustry(Commands cmd, const CommandCost &result, TileIndex tile, IndustryType indtype, uint32_t, bool, uint32_t)
Command callback.
uint32_t _frame_counter
The current frame.
Definition: network.cpp:78
bool _network_server
network-server is active
Definition: network.cpp:66
uint32_t _frame_counter_max
To where we may go with our clients.
Definition: network.cpp:77
void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket &cp)
Distribute CommandPacket details over the admin network for logging purposes.
Server part of the admin network protocol.
Client part of the network protocol.
static void SetClientIdHelper(T &data, [[maybe_unused]] ClientID client_id)
Helper to process a single ClientID argument.
static void SanitizeStringsHelper(CommandFlags cmd_flags, Ttuple &values, std::index_sequence< Tindices... >)
Helper function to perform validation on command data strings.
static constexpr auto _callback_tuple
Typed list of all possible callbacks.
static void SanitizeSingleStringHelper([[maybe_unused]] CommandFlags cmd_flags, T &data)
Validate a single string argument coming from network.
void NetworkFreeLocalCommandQueue()
Free the local command queues.
static void SetClientIds(Ttuple &values, ClientID client_id, std::index_sequence< Tindices... >)
Set all invalid ClientID's to the proper value.
static size_t FindCallbackIndex(CommandCallback *callback)
Find the callback index of a callback pointer.
void NetworkExecuteLocalCommandQueue()
Execute all commands on the local command queue that ought to be executed this frame.
void NetworkDistributeCommands()
Distribute the commands of ourself and the clients.
static CommandQueue _local_wait_queue
Local queue of packets waiting for handling.
static CommandQueue _local_execution_queue
Local queue of packets waiting for execution.
static void DistributeCommandPacket(CommandPacket &cp, const NetworkClientSocket *owner)
"Send" a particular CommandPacket to all clients.
static auto _callback_table
Type-erased table of callbacks.
void NetworkSyncCommandQueue(NetworkClientSocket *cs)
Sync our local command queue to the command queue of the given socket.
static void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id)
Insert a client ID into the command data in a command packet.
static void UnpackNetworkCommand(const CommandPacket &cp)
Unpack a generic command packet into its actual typed components.
static void DistributeQueue(CommandQueue &queue, const NetworkClientSocket *owner)
"Send" a particular CommandQueue to all clients.
void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, const CommandDataBuffer &cmd_data)
Prepare a DoCommand to be send over the network.
static CommandDataBuffer SanitizeCmdStrings(const CommandDataBuffer &data)
Validate and sanitize strings in command data.
static constexpr auto _cmd_dispatch
Command dispatch table.
Server part of the network protocol.
ClientID
'Unique' identifier to be given to clients
Definition: network_type.h:49
@ PM_UNPAUSED
A normal unpaused game.
Definition: openttd.h:69
void CcBuildRailTunnel(Commands, const CommandCost &result, TileIndex tile)
Command callback for building a tunnel.
Definition: rail_gui.cpp:303
void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8_t width, uint8_t length, RoadStopType, bool is_drive_through, DiagDirection dir, RoadType, RoadStopClassID spec_class, uint16_t spec_index, StationID, bool)
Command callback for building road stops.
Definition: road_gui.cpp:194
void CcBuildRoadTunnel(Commands, const CommandCost &result, TileIndex start_tile)
Callback executed after a build road tunnel command has been called.
Definition: road_gui.cpp:140
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:56
void CcPlaceSign(Commands, const CommandCost &result, SignID new_sign)
Callback function that is called after a sign is placed.
Definition: signs_cmd.cpp:108
static void StrMakeValid(T &dst, const char *str, const char *last, StringValidationSettings settings)
Copies the valid (UTF-8) characters from str up to last to the dst.
Definition: string.cpp:107
@ SVS_ALLOW_CONTROL_CODE
Allow the special control codes.
Definition: string_type.h:48
@ SVS_REPLACE_WITH_QUESTION_MARK
Replace the unknown/bad bits with question marks.
Definition: string_type.h:46
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
NetworkSettings network
settings related to the network
Everything we need to know about a command to be able to execute it.
StringID err_msg
string ID of error message to use.
CommandDataBuffer data
command parameters.
CommandCallback * callback
any callback function executed upon successful completion of the command.
uint32_t frame
the frame in which this packet is executed
CompanyID company
company that is executing the command
bool my_cmd
did the command originate from "me"
Commands cmd
command being executed.
Defines the traits of a command.
Definition: command_type.h:453
uint16_t commands_per_frame
how many commands may be sent each frame_freq frames?
uint16_t commands_per_frame_server
how many commands may be sent each frame_freq frames? (server-originating commands)
Internal entity of a packet.
Definition: packet.h:42
uint16_t Recv_uint16()
Read a 16 bits integer from the packet.
Definition: packet.cpp:332
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:318
void Send_uint8(uint8_t data)
Package a 8 bits integer in the packet.
Definition: packet.cpp:120
void Send_buffer(const std::vector< uint8_t > &data)
Copy a sized byte buffer into the packet.
Definition: packet.cpp:183
std::vector< uint8_t > Recv_buffer()
Extract a sized byte buffer from the packet.
Definition: packet.cpp:385
void Send_uint16(uint16_t data)
Package a 16 bits integer in the packet.
Definition: packet.cpp:130
std::vector< CommandPacket > CommandQueue
A "queue" of CommandPackets.
Definition: tcp_game.h:138
void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16_t, CargoArray, TileIndex tile, EngineID, bool, CargoID, ClientID)
Callback for building wagons.
Definition: train_gui.cpp:29
void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id, bool)
This is the Callback method after attempting to start/stop a vehicle.
void CcBuildPrimaryVehicle(Commands, const CommandCost &result, VehicleID new_veh_id, uint, uint16_t, CargoArray)
This is the Callback method after the construction attempt of a primary vehicle.