|
|
|
@ -63,10 +63,14 @@ static CommandCallback * const _callback_table[] = {
|
|
|
|
|
* @param p The packet to append to the queue.
|
|
|
|
|
* @note A new instance of the CommandPacket will be made.
|
|
|
|
|
*/
|
|
|
|
|
void CommandQueue::Append(CommandPacket *p)
|
|
|
|
|
void CommandQueue::Append(CommandPacket *p, bool move)
|
|
|
|
|
{
|
|
|
|
|
CommandPacket *add = MallocT<CommandPacket>(1);
|
|
|
|
|
*add = *p;
|
|
|
|
|
CommandPacket *add = new CommandPacket();
|
|
|
|
|
if (move) {
|
|
|
|
|
*add = std::move(*p);
|
|
|
|
|
} else {
|
|
|
|
|
*add = *p;
|
|
|
|
|
}
|
|
|
|
|
add->next = NULL;
|
|
|
|
|
if (this->first == NULL) {
|
|
|
|
|
this->first = add;
|
|
|
|
@ -82,8 +86,9 @@ void CommandQueue::Append(CommandPacket *p)
|
|
|
|
|
* @param ignore_paused Whether to ignore commands that may not be executed while paused.
|
|
|
|
|
* @return the first item in the queue.
|
|
|
|
|
*/
|
|
|
|
|
CommandPacket *CommandQueue::Pop(bool ignore_paused)
|
|
|
|
|
std::unique_ptr<CommandPacket> CommandQueue::Pop(bool ignore_paused)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
CommandPacket **prev = &this->first;
|
|
|
|
|
CommandPacket *ret = this->first;
|
|
|
|
|
CommandPacket *prev_item = NULL;
|
|
|
|
@ -99,7 +104,7 @@ CommandPacket *CommandQueue::Pop(bool ignore_paused)
|
|
|
|
|
*prev = ret->next;
|
|
|
|
|
this->count--;
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
return std::unique_ptr<CommandPacket>(ret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -120,10 +125,8 @@ CommandPacket *CommandQueue::Peek(bool ignore_paused)
|
|
|
|
|
/** Free everything that is in the queue. */
|
|
|
|
|
void CommandQueue::Free()
|
|
|
|
|
{
|
|
|
|
|
CommandPacket *cp;
|
|
|
|
|
while ((cp = this->Pop()) != NULL) {
|
|
|
|
|
free(cp);
|
|
|
|
|
}
|
|
|
|
|
std::unique_ptr<CommandPacket> cp;
|
|
|
|
|
while ((cp = this->Pop()) != NULL) {}
|
|
|
|
|
assert(this->count == 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -157,9 +160,13 @@ void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, Comman
|
|
|
|
|
|
|
|
|
|
c.binary_length = binary_length;
|
|
|
|
|
if (binary_length == 0) {
|
|
|
|
|
strecpy(c.text, (text != NULL) ? text : "", lastof(c.text));
|
|
|
|
|
if (text != NULL) {
|
|
|
|
|
c.text.assign(text);
|
|
|
|
|
} else {
|
|
|
|
|
c.text.clear();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
memcpy(c.text, text, binary_length);
|
|
|
|
|
c.text.assign(text, binary_length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_network_server) {
|
|
|
|
@ -172,7 +179,7 @@ void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, Comman
|
|
|
|
|
c.frame = _frame_counter_max + 1;
|
|
|
|
|
c.my_cmd = true;
|
|
|
|
|
|
|
|
|
|
_local_wait_queue.Append(&c);
|
|
|
|
|
_local_wait_queue.Append(std::move(c));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -196,7 +203,7 @@ void NetworkSyncCommandQueue(NetworkClientSocket *cs)
|
|
|
|
|
for (CommandPacket *p = _local_execution_queue.Peek(); p != NULL; p = p->next) {
|
|
|
|
|
CommandPacket c = *p;
|
|
|
|
|
c.callback = 0;
|
|
|
|
|
cs->outgoing_queue.Append(&c);
|
|
|
|
|
cs->outgoing_queue.Append(std::move(c));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -227,7 +234,6 @@ void NetworkExecuteLocalCommandQueue()
|
|
|
|
|
DoCommandP(cp, cp->my_cmd);
|
|
|
|
|
|
|
|
|
|
queue.Pop();
|
|
|
|
|
free(cp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Local company may have changed, so we should not restore the old value */
|
|
|
|
@ -260,13 +266,13 @@ static void DistributeCommandPacket(CommandPacket &cp, const NetworkClientSocket
|
|
|
|
|
* first place. This filters that out. */
|
|
|
|
|
cp.callback = (cs != owner) ? NULL : callback;
|
|
|
|
|
cp.my_cmd = (cs == owner);
|
|
|
|
|
cs->outgoing_queue.Append(&cp);
|
|
|
|
|
cs->outgoing_queue.Append(cp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cp.callback = (cs != owner) ? NULL : callback;
|
|
|
|
|
cp.my_cmd = (cs == owner);
|
|
|
|
|
_local_execution_queue.Append(&cp);
|
|
|
|
|
_local_execution_queue.Append(cp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -283,11 +289,10 @@ static void DistributeQueue(CommandQueue *queue, const NetworkClientSocket *owne
|
|
|
|
|
int to_go = _settings_client.network.commands_per_frame;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
CommandPacket *cp;
|
|
|
|
|
std::unique_ptr<CommandPacket> cp;
|
|
|
|
|
while (--to_go >= 0 && (cp = queue->Pop(true)) != NULL) {
|
|
|
|
|
DistributeCommandPacket(*cp, owner);
|
|
|
|
|
NetworkAdminCmdLogging(owner, cp);
|
|
|
|
|
free(cp);
|
|
|
|
|
NetworkAdminCmdLogging(owner, cp.get());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -323,9 +328,10 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c
|
|
|
|
|
cp->tile = p->Recv_uint32();
|
|
|
|
|
cp->binary_length = p->Recv_uint32();
|
|
|
|
|
if (cp->binary_length == 0) {
|
|
|
|
|
p->Recv_string(cp->text, lengthof(cp->text), (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK);
|
|
|
|
|
p->Recv_string(cp->text, (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK);
|
|
|
|
|
} else {
|
|
|
|
|
if ((p->pos + (PacketSize) cp->binary_length + /* callback index */ 1) > p->size) return "invalid binary data length";
|
|
|
|
|
if (cp->binary_length > MAX_CMD_TEXT_LENGTH) return "over-size binary data length";
|
|
|
|
|
p->Recv_binary(cp->text, cp->binary_length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -350,9 +356,10 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp)
|
|
|
|
|
p->Send_uint32(cp->tile);
|
|
|
|
|
p->Send_uint32(cp->binary_length);
|
|
|
|
|
if (cp->binary_length == 0) {
|
|
|
|
|
p->Send_string(cp->text);
|
|
|
|
|
p->Send_string(cp->text.c_str());
|
|
|
|
|
} else {
|
|
|
|
|
p->Send_binary(cp->text, cp->binary_length);
|
|
|
|
|
assert(cp->text.size() >= cp->binary_length);
|
|
|
|
|
p->Send_binary(cp->text.c_str(), cp->binary_length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
byte callback = 0;
|
|
|
|
|