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_internal.h"
00017 #include "network_client.h"
00018 #include "../command_func.h"
00019 #include "../callback_table.h"
00020 #include "../company_func.h"
00021
00023 static CommandPacket *_local_command_queue = NULL;
00024
00031 void NetworkAddCommandQueue(CommandPacket cp, NetworkClientSocket *cs)
00032 {
00033 CommandPacket *new_cp = MallocT<CommandPacket>(1);
00034 *new_cp = cp;
00035
00036 CommandPacket **begin = (cs == NULL ? &_local_command_queue : &cs->command_queue);
00037
00038 if (*begin == NULL) {
00039 *begin = new_cp;
00040 } else {
00041 CommandPacket *c = *begin;
00042 while (c->next != NULL) c = c->next;
00043 c->next = new_cp;
00044 }
00045 }
00046
00056 void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text)
00057 {
00058 assert((cmd & CMD_FLAGS_MASK) == 0);
00059
00060 CommandPacket c;
00061 c.company = _local_company;
00062 c.next = NULL;
00063 c.tile = tile;
00064 c.p1 = p1;
00065 c.p2 = p2;
00066 c.cmd = cmd;
00067 c.callback = callback;
00068
00069 strecpy(c.text, (text != NULL) ? text : "", lastof(c.text));
00070
00071 if (_network_server) {
00072
00073
00074
00075
00076
00077
00078 c.frame = _frame_counter_max + 1;
00079 c.my_cmd = true;
00080
00081 NetworkAddCommandQueue(c);
00082
00083
00084 c.callback = 0;
00085
00086 NetworkClientSocket *cs;
00087 FOR_ALL_CLIENT_SOCKETS(cs) {
00088 if (cs->status > STATUS_MAP_WAIT) NetworkAddCommandQueue(c, cs);
00089 }
00090 return;
00091 }
00092
00093 c.frame = 0;
00094
00095
00096 SEND_COMMAND(PACKET_CLIENT_COMMAND)(&c);
00097 }
00098
00102 void NetworkExecuteLocalCommandQueue()
00103 {
00104 while (_local_command_queue != NULL) {
00105
00106
00107
00108 if (_frame_counter < _local_command_queue->frame) break;
00109
00110 if (_frame_counter > _local_command_queue->frame) {
00111
00112
00113 error("[net] Trying to execute a packet in the past!");
00114 }
00115
00116 CommandPacket *cp = _local_command_queue;
00117
00118
00119 _current_company = cp->company;
00120 cp->cmd |= CMD_NETWORK_COMMAND;
00121 DoCommandP(cp, cp->my_cmd);
00122
00123 _local_command_queue = _local_command_queue->next;
00124 free(cp);
00125 }
00126 }
00127
00131 void NetworkFreeLocalCommandQueue()
00132 {
00133
00134 while (_local_command_queue != NULL) {
00135 CommandPacket *p = _local_command_queue;
00136 _local_command_queue = _local_command_queue->next;
00137 free(p);
00138 }
00139 }
00140
00147 const char *NetworkClientSocket::Recv_Command(Packet *p, CommandPacket *cp)
00148 {
00149 cp->company = (CompanyID)p->Recv_uint8();
00150 cp->cmd = p->Recv_uint32();
00151 cp->p1 = p->Recv_uint32();
00152 cp->p2 = p->Recv_uint32();
00153 cp->tile = p->Recv_uint32();
00154 p->Recv_string(cp->text, lengthof(cp->text));
00155
00156 byte callback = p->Recv_uint8();
00157
00158 if (!IsValidCommand(cp->cmd)) return "invalid command";
00159 if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "offline only command";
00160 if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag";
00161 if (callback > _callback_table_count) return "invalid callback";
00162
00163 cp->callback = _callback_table[callback];
00164 return NULL;
00165 }
00166
00172 void NetworkClientSocket::Send_Command(Packet *p, const CommandPacket *cp)
00173 {
00174 p->Send_uint8 (cp->company);
00175 p->Send_uint32(cp->cmd);
00176 p->Send_uint32(cp->p1);
00177 p->Send_uint32(cp->p2);
00178 p->Send_uint32(cp->tile);
00179 p->Send_string(cp->text);
00180
00181 byte callback = 0;
00182 while (callback < _callback_table_count && _callback_table[callback] != cp->callback) {
00183 callback++;
00184 }
00185
00186 if (callback == _callback_table_count) {
00187 DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", cp->callback);
00188 callback = 0;
00189 }
00190 p->Send_uint8 (callback);
00191 }
00192
00193 #endif