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 #ifdef ENABLE_AI
00042 CcAI,
00043 #else
00044 NULL,
00045 #endif
00046 CcCloneVehicle,
00047 CcGiveMoney,
00048 CcCreateGroup,
00049 CcFoundRandomTown,
00050 };
00051
00053 static CommandPacket *_local_command_queue = NULL;
00054
00061 void NetworkAddCommandQueue(CommandPacket cp, NetworkClientSocket *cs)
00062 {
00063 CommandPacket *new_cp = MallocT<CommandPacket>(1);
00064 *new_cp = cp;
00065
00066 CommandPacket **begin = (cs == NULL ? &_local_command_queue : &cs->command_queue);
00067
00068 if (*begin == NULL) {
00069 *begin = new_cp;
00070 } else {
00071 CommandPacket *c = *begin;
00072 while (c->next != NULL) c = c->next;
00073 c->next = new_cp;
00074 }
00075 }
00076
00087 void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company)
00088 {
00089 assert((cmd & CMD_FLAGS_MASK) == 0);
00090
00091 CommandPacket c;
00092 c.company = company;
00093 c.next = NULL;
00094 c.tile = tile;
00095 c.p1 = p1;
00096 c.p2 = p2;
00097 c.cmd = cmd;
00098 c.callback = callback;
00099
00100 strecpy(c.text, (text != NULL) ? text : "", lastof(c.text));
00101
00102 if (_network_server) {
00103
00104
00105
00106
00107
00108
00109 c.frame = _frame_counter_max + 1;
00110 c.my_cmd = true;
00111
00112 NetworkAddCommandQueue(c);
00113
00114
00115 c.callback = 0;
00116
00117 NetworkClientSocket *cs;
00118 FOR_ALL_CLIENT_SOCKETS(cs) {
00119 if (cs->status > STATUS_MAP_WAIT) NetworkAddCommandQueue(c, cs);
00120 }
00121 return;
00122 }
00123
00124 c.frame = 0;
00125
00126
00127 SEND_COMMAND(PACKET_CLIENT_COMMAND)(&c);
00128 }
00129
00133 void NetworkExecuteLocalCommandQueue()
00134 {
00135 while (_local_command_queue != NULL) {
00136
00137
00138
00139 if (_frame_counter < _local_command_queue->frame) break;
00140
00141 if (_frame_counter > _local_command_queue->frame) {
00142
00143
00144 error("[net] Trying to execute a packet in the past!");
00145 }
00146
00147 CommandPacket *cp = _local_command_queue;
00148
00149
00150 _current_company = cp->company;
00151 cp->cmd |= CMD_NETWORK_COMMAND;
00152 DoCommandP(cp, cp->my_cmd);
00153
00154 _local_command_queue = _local_command_queue->next;
00155 free(cp);
00156 }
00157 }
00158
00162 void NetworkFreeLocalCommandQueue()
00163 {
00164
00165 while (_local_command_queue != NULL) {
00166 CommandPacket *p = _local_command_queue;
00167 _local_command_queue = _local_command_queue->next;
00168 free(p);
00169 }
00170 }
00171
00178 const char *NetworkClientSocket::Recv_Command(Packet *p, CommandPacket *cp)
00179 {
00180 cp->company = (CompanyID)p->Recv_uint8();
00181 cp->cmd = p->Recv_uint32();
00182 cp->p1 = p->Recv_uint32();
00183 cp->p2 = p->Recv_uint32();
00184 cp->tile = p->Recv_uint32();
00185 p->Recv_string(cp->text, lengthof(cp->text));
00186
00187 byte callback = p->Recv_uint8();
00188
00189 if (!IsValidCommand(cp->cmd)) return "invalid command";
00190 if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "offline only command";
00191 if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag";
00192 if (callback > lengthof(_callback_table)) return "invalid callback";
00193
00194 cp->callback = _callback_table[callback];
00195 return NULL;
00196 }
00197
00203 void NetworkClientSocket::Send_Command(Packet *p, const CommandPacket *cp)
00204 {
00205 p->Send_uint8 (cp->company);
00206 p->Send_uint32(cp->cmd);
00207 p->Send_uint32(cp->p1);
00208 p->Send_uint32(cp->p2);
00209 p->Send_uint32(cp->tile);
00210 p->Send_string(cp->text);
00211
00212 byte callback = 0;
00213 while (callback < lengthof(_callback_table) && _callback_table[callback] != cp->callback) {
00214 callback++;
00215 }
00216
00217 if (callback == lengthof(_callback_table)) {
00218 DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", cp->callback);
00219 callback = 0;
00220 }
00221 p->Send_uint8 (callback);
00222 }
00223
00224 #endif