BOOL DM::DiskMaster::SendCommand( DM_CMD_MSG_HEADER &cmd ) { DMT_TRACE(" Send command: code %d, size %d\n", cmd.code, cmd.param_size); assert(IsValidCommand(cmd.code)); BYTE *param = NULL; if (sizeof(DM_CMD_MSG_HEADER) == io->Write(&cmd, sizeof(DM_CMD_MSG_HEADER))) { if (!cmd.param_size) { last_cmd = cmd.code; return TRUE; } else ::Sleep(DM_SEND_COMMAND_DELAY); param = &((BYTE *)&cmd)[sizeof(DM_CMD_MSG_HEADER)]; if (cmd.param_size == io->Write(param, cmd.param_size)) { MSG_GET_COMMAND get_cmd; WORD check_code = 0; switch(cmd.code) { case kCmdCheckReady: if (sizeof(check_code) == io->Read(&check_code, sizeof(check_code))) { assert(check_code == *(&((WORD *)&cmd)[2])); last_cmd = cmd.code; DMT_TRACE(" OK\n"); return TRUE; } break; case kCmdBoardOff: last_cmd = cmd.code; return TRUE; case kCmdBoardOn: case kCmdSendOption: case kCmdSendTask: case kCmdSetSataSize: case kCmdSetCopyOffset: case kCmdCopyBlock: case kCmdTestBlock: case kCmdEraseBlock: case kCmdReadLbaHdd1: case kCmdReadLbaHdd2: case kCmdWriteLbaHdd2: if (sizeof(MSG_GET_COMMAND) == io->Read(&get_cmd, sizeof(MSG_GET_COMMAND))) { assert(get_cmd.code == kMsgGetCommand); assert(get_cmd.param == cmd.code); last_cmd = cmd.code; DMT_TRACE(" OK\n"); return TRUE; } break; default : DMT_TRACE(" ERROR\n"); return FALSE; } } } DMT_TRACE(" ERROR\n"); return FALSE; }
/** * Receives a command from the network. * @param p the packet to read from. * @param cp the struct to write the data to. * @return an error message. When NULL there has been no error. */ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *cp) { cp->company = (CompanyID)p->Recv_uint8(); cp->cmd = p->Recv_uint32(); if (!IsValidCommand(cp->cmd)) return "invalid command"; if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "offline only command"; if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag"; cp->p1 = p->Recv_uint32(); cp->p2 = p->Recv_uint32(); cp->tile = p->Recv_uint32(); 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); byte callback = p->Recv_uint8(); if (callback >= lengthof(_callback_table)) return "invalid callback"; cp->callback = _callback_table[callback]; return NULL; }
/** * Returns whether the command is allowed while the game is paused. * @param cmd The command to check. * @return True if the command is allowed while paused, false otherwise. */ bool IsCommandAllowedWhilePaused(uint32 cmd) { /* Lookup table for the command types that are allowed for a given pause level setting. */ static const int command_type_lookup[] = { CMDPL_ALL_ACTIONS, ///< CMDT_LANDSCAPE_CONSTRUCTION CMDPL_NO_LANDSCAPING, ///< CMDT_VEHICLE_CONSTRUCTION CMDPL_NO_LANDSCAPING, ///< CMDT_MONEY_MANAGEMENT CMDPL_NO_CONSTRUCTION, ///< CMDT_VEHICLE_MANAGEMENT CMDPL_NO_CONSTRUCTION, ///< CMDT_ROUTE_MANAGEMENT CMDPL_NO_CONSTRUCTION, ///< CMDT_OTHER_MANAGEMENT CMDPL_NO_CONSTRUCTION, ///< CMDT_COMPANY_SETTING CMDPL_NO_ACTIONS, ///< CMDT_SERVER_SETTING CMDPL_NO_ACTIONS, ///< CMDT_CHEAT }; assert_compile(lengthof(command_type_lookup) == CMDT_END); assert(IsValidCommand(cmd)); return _game_mode == GM_EDITOR || command_type_lookup[_command_proc_table[cmd & CMD_ID_MASK].type] <= _settings_game.construction.command_pause_level; }
/** * Receives a command from the network. * @param p the packet to read from. * @param cp the struct to write the data to. * @return an error message. When NULL there has been no error. */ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *cp) { cp->company = (CompanyID)p->Recv_uint8(); cp->cmd = p->Recv_uint32(); cp->p1 = p->Recv_uint32(); cp->p2 = p->Recv_uint32(); cp->tile = p->Recv_uint32(); p->Recv_string(cp->text, lengthof(cp->text)); byte callback = p->Recv_uint8(); if (!IsValidCommand(cp->cmd)) return "invalid command"; if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "offline only command"; if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag"; if (callback >= lengthof(_callback_table)) return "invalid callback"; cp->callback = _callback_table[callback]; return NULL; }
/*! * This function mask the parameter with CMD_ID_MASK and returns * the flags which belongs to the given command. * * @param cmd The integer value of the command * @return The flags for this command */ byte GetCommandFlags(uint32 cmd) { assert(IsValidCommand(cmd)); return _command_proc_table[cmd & CMD_ID_MASK].flags; }
/*! * This function mask the parameter with CMD_ID_MASK and returns * the name which belongs to the given command. * * @param cmd The integer value of the command * @return The name for this command */ const char *GetCommandName(uint32 cmd) { assert(IsValidCommand(cmd)); return _command_proc_table[cmd & CMD_ID_MASK].name; }