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
00139 void NetworkSyncCommandQueue(NetworkClientSocket *cs)
00140 {
00141 for (CommandPacket *p = _local_command_queue; p != NULL; p = p->next) {
00142 CommandPacket c = *p;
00143 c.callback = 0;
00144 NetworkAddCommandQueue(c, cs);
00145 }
00146 }
00147
00151 void NetworkExecuteLocalCommandQueue()
00152 {
00153 while (_local_command_queue != NULL) {
00154
00155
00156
00157 if (_frame_counter < _local_command_queue->frame) break;
00158
00159 if (_frame_counter > _local_command_queue->frame) {
00160
00161
00162 error("[net] Trying to execute a packet in the past!");
00163 }
00164
00165 CommandPacket *cp = _local_command_queue;
00166
00167
00168 _current_company = cp->company;
00169 cp->cmd |= CMD_NETWORK_COMMAND;
00170 DoCommandP(cp, cp->my_cmd);
00171
00172 _local_command_queue = _local_command_queue->next;
00173 free(cp);
00174 }
00175 }
00176
00180 void NetworkFreeLocalCommandQueue()
00181 {
00182
00183 while (_local_command_queue != NULL) {
00184 CommandPacket *p = _local_command_queue;
00185 _local_command_queue = _local_command_queue->next;
00186 free(p);
00187 }
00188 }
00189
00196 const char *NetworkClientSocket::Recv_Command(Packet *p, CommandPacket *cp)
00197 {
00198 cp->company = (CompanyID)p->Recv_uint8();
00199 cp->cmd = p->Recv_uint32();
00200 cp->p1 = p->Recv_uint32();
00201 cp->p2 = p->Recv_uint32();
00202 cp->tile = p->Recv_uint32();
00203 p->Recv_string(cp->text, lengthof(cp->text));
00204
00205 byte callback = p->Recv_uint8();
00206
00207 if (!IsValidCommand(cp->cmd)) return "invalid command";
00208 if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "offline only command";
00209 if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag";
00210 if (callback > lengthof(_callback_table)) return "invalid callback";
00211
00212 cp->callback = _callback_table[callback];
00213 return NULL;
00214 }
00215
00221 void NetworkClientSocket::Send_Command(Packet *p, const CommandPacket *cp)
00222 {
00223 p->Send_uint8 (cp->company);
00224 p->Send_uint32(cp->cmd);
00225 p->Send_uint32(cp->p1);
00226 p->Send_uint32(cp->p2);
00227 p->Send_uint32(cp->tile);
00228 p->Send_string(cp->text);
00229
00230 byte callback = 0;
00231 while (callback < lengthof(_callback_table) && _callback_table[callback] != cp->callback) {
00232 callback++;
00233 }
00234
00235 if (callback == lengthof(_callback_table)) {
00236 DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", cp->callback);
00237 callback = 0;
00238 }
00239 p->Send_uint8 (callback);
00240 }
00241
00242 #endif