network_command.cpp
Go to the documentation of this file.00001
00002
00005 #ifdef ENABLE_NETWORK
00006
00007 #include "../stdafx.h"
00008 #include "../debug.h"
00009 #include "network_internal.h"
00010 #include "network_client.h"
00011 #include "../command_func.h"
00012 #include "../callback_table.h"
00013 #include "../core/alloc_func.hpp"
00014 #include "../string_func.h"
00015 #include "../company_func.h"
00016
00018 static CommandPacket *_local_command_queue = NULL;
00019
00026 void NetworkAddCommandQueue(CommandPacket cp, NetworkClientSocket *cs)
00027 {
00028 CommandPacket *new_cp = MallocT<CommandPacket>(1);
00029 *new_cp = cp;
00030
00031 CommandPacket **begin = (cs == NULL ? &_local_command_queue : &cs->command_queue);
00032
00033 if (*begin == NULL) {
00034 *begin = new_cp;
00035 } else {
00036 CommandPacket *c = *begin;
00037 while (c->next != NULL) c = c->next;
00038 c->next = new_cp;
00039 }
00040 }
00041
00051 void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text)
00052 {
00053 assert((cmd & CMD_FLAGS_MASK) == 0);
00054
00055 CommandPacket c;
00056 c.company = _local_company;
00057 c.next = NULL;
00058 c.tile = tile;
00059 c.p1 = p1;
00060 c.p2 = p2;
00061 c.cmd = cmd;
00062 c.callback = callback;
00063
00064 strecpy(c.text, (text != NULL) ? text : "", lastof(c.text));
00065
00066 if (_network_server) {
00067
00068
00069
00070
00071
00072
00073 c.frame = _frame_counter_max + 1;
00074 c.my_cmd = true;
00075
00076 NetworkAddCommandQueue(c);
00077
00078
00079 c.callback = 0;
00080
00081 NetworkClientSocket *cs;
00082 FOR_ALL_CLIENT_SOCKETS(cs) {
00083 if (cs->status > STATUS_MAP_WAIT) NetworkAddCommandQueue(c, cs);
00084 }
00085 return;
00086 }
00087
00088 c.frame = 0;
00089
00090
00091 SEND_COMMAND(PACKET_CLIENT_COMMAND)(&c);
00092 }
00093
00097 void NetworkExecuteLocalCommandQueue()
00098 {
00099 while (_local_command_queue != NULL) {
00100
00101
00102
00103 if (_frame_counter < _local_command_queue->frame) break;
00104
00105 if (_frame_counter > _local_command_queue->frame) {
00106
00107
00108 error("[net] Trying to execute a packet in the past!");
00109 }
00110
00111 CommandPacket *cp = _local_command_queue;
00112
00113
00114 _current_company = cp->company;
00115 cp->cmd |= CMD_NETWORK_COMMAND;
00116 DoCommandP(cp, cp->my_cmd);
00117
00118 _local_command_queue = _local_command_queue->next;
00119 free(cp);
00120 }
00121 }
00122
00126 void NetworkFreeLocalCommandQueue()
00127 {
00128
00129 while (_local_command_queue != NULL) {
00130 CommandPacket *p = _local_command_queue;
00131 _local_command_queue = _local_command_queue->next;
00132 free(p);
00133 }
00134 }
00135
00142 const char *NetworkClientSocket::Recv_Command(Packet *p, CommandPacket *cp)
00143 {
00144 cp->company = (CompanyID)p->Recv_uint8();
00145 cp->cmd = p->Recv_uint32();
00146 cp->p1 = p->Recv_uint32();
00147 cp->p2 = p->Recv_uint32();
00148 cp->tile = p->Recv_uint32();
00149 p->Recv_string(cp->text, lengthof(cp->text));
00150
00151 byte callback = p->Recv_uint8();
00152
00153 if (!IsValidCommand(cp->cmd)) return "invalid command";
00154 if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "offline only command";
00155 if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag";
00156 if (callback > _callback_table_count) return "invalid callback";
00157
00158 cp->callback = _callback_table[callback];
00159 return NULL;
00160 }
00161
00167 void NetworkClientSocket::Send_Command(Packet *p, const CommandPacket *cp)
00168 {
00169 p->Send_uint8 (cp->company);
00170 p->Send_uint32(cp->cmd);
00171 p->Send_uint32(cp->p1);
00172 p->Send_uint32(cp->p2);
00173 p->Send_uint32(cp->tile);
00174 p->Send_string(cp->text);
00175
00176 byte callback = 0;
00177 while (callback < _callback_table_count && _callback_table[callback] != cp->callback) {
00178 callback++;
00179 }
00180
00181 if (callback == _callback_table_count) {
00182 DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
00183 callback = 0;
00184 }
00185 p->Send_uint8 (callback);
00186 }
00187
00188 #endif