network_command.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifdef ENABLE_NETWORK
00013
00014 #include "../stdafx.h"
00015 #include "../debug.h"
00016 #include "network_client.h"
00017 #include "network.h"
00018 #include "../command_func.h"
00019 #include "../company_func.h"
00020
00022 static CommandCallback * const _callback_table[] = {
00023 NULL,
00024 CcBuildPrimaryVehicle,
00025 CcBuildAirport,
00026 CcBuildBridge,
00027 CcBuildCanal,
00028 CcBuildDocks,
00029 CcFoundTown,
00030 CcBuildRoadTunnel,
00031 CcBuildRailTunnel,
00032 CcBuildWagon,
00033 CcRoadDepot,
00034 CcRailDepot,
00035 CcPlaceSign,
00036 CcPlaySound10,
00037 CcPlaySound1D,
00038 CcPlaySound1E,
00039 CcStation,
00040 CcTerraform,
00041 CcAI,
00042 CcCloneVehicle,
00043 CcGiveMoney,
00044 CcCreateGroup,
00045 CcFoundRandomTown,
00046 };
00047
00049 static CommandPacket *_local_command_queue = NULL;
00050
00057 void NetworkAddCommandQueue(CommandPacket cp, NetworkClientSocket *cs)
00058 {
00059 CommandPacket *new_cp = MallocT<CommandPacket>(1);
00060 *new_cp = cp;
00061
00062 CommandPacket **begin = (cs == NULL ? &_local_command_queue : &cs->command_queue);
00063
00064 if (*begin == NULL) {
00065 *begin = new_cp;
00066 } else {
00067 CommandPacket *c = *begin;
00068 while (c->next != NULL) c = c->next;
00069 c->next = new_cp;
00070 }
00071 }
00072
00083 void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company)
00084 {
00085 assert((cmd & CMD_FLAGS_MASK) == 0);
00086
00087 CommandPacket c;
00088 c.company = company;
00089 c.next = NULL;
00090 c.tile = tile;
00091 c.p1 = p1;
00092 c.p2 = p2;
00093 c.cmd = cmd;
00094 c.callback = callback;
00095
00096 strecpy(c.text, (text != NULL) ? text : "", lastof(c.text));
00097
00098 if (_network_server) {
00099
00100
00101
00102
00103
00104
00105 c.frame = _frame_counter_max + 1;
00106 c.my_cmd = true;
00107
00108 NetworkAddCommandQueue(c);
00109
00110
00111 c.callback = 0;
00112
00113 NetworkClientSocket *cs;
00114 FOR_ALL_CLIENT_SOCKETS(cs) {
00115 if (cs->status > STATUS_MAP_WAIT) NetworkAddCommandQueue(c, cs);
00116 }
00117 return;
00118 }
00119
00120 c.frame = 0;
00121
00122
00123 SEND_COMMAND(PACKET_CLIENT_COMMAND)(&c);
00124 }
00125
00129 void NetworkExecuteLocalCommandQueue()
00130 {
00131 while (_local_command_queue != NULL) {
00132
00133
00134
00135 if (_frame_counter < _local_command_queue->frame) break;
00136
00137 if (_frame_counter > _local_command_queue->frame) {
00138
00139
00140 error("[net] Trying to execute a packet in the past!");
00141 }
00142
00143 CommandPacket *cp = _local_command_queue;
00144
00145
00146 _current_company = cp->company;
00147 cp->cmd |= CMD_NETWORK_COMMAND;
00148 DoCommandP(cp, cp->my_cmd);
00149
00150 _local_command_queue = _local_command_queue->next;
00151 free(cp);
00152 }
00153 }
00154
00158 void NetworkFreeLocalCommandQueue()
00159 {
00160
00161 while (_local_command_queue != NULL) {
00162 CommandPacket *p = _local_command_queue;
00163 _local_command_queue = _local_command_queue->next;
00164 free(p);
00165 }
00166 }
00167
00174 const char *NetworkClientSocket::Recv_Command(Packet *p, CommandPacket *cp)
00175 {
00176 cp->company = (CompanyID)p->Recv_uint8();
00177 cp->cmd = p->Recv_uint32();
00178 cp->p1 = p->Recv_uint32();
00179 cp->p2 = p->Recv_uint32();
00180 cp->tile = p->Recv_uint32();
00181 p->Recv_string(cp->text, lengthof(cp->text));
00182
00183 byte callback = p->Recv_uint8();
00184
00185 if (!IsValidCommand(cp->cmd)) return "invalid command";
00186 if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "offline only command";
00187 if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag";
00188 if (callback > lengthof(_callback_table)) return "invalid callback";
00189
00190 cp->callback = _callback_table[callback];
00191 return NULL;
00192 }
00193
00199 void NetworkClientSocket::Send_Command(Packet *p, const CommandPacket *cp)
00200 {
00201 p->Send_uint8 (cp->company);
00202 p->Send_uint32(cp->cmd);
00203 p->Send_uint32(cp->p1);
00204 p->Send_uint32(cp->p2);
00205 p->Send_uint32(cp->tile);
00206 p->Send_string(cp->text);
00207
00208 byte callback = 0;
00209 while (callback < lengthof(_callback_table) && _callback_table[callback] != cp->callback) {
00210 callback++;
00211 }
00212
00213 if (callback == lengthof(_callback_table)) {
00214 DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", cp->callback);
00215 callback = 0;
00216 }
00217 p->Send_uint8 (callback);
00218 }
00219
00220 #endif