static void NETcoder(PACKETDIR dir) { static const char original[] = "THIS IS A TEST STRING"; char str[sizeof(original)]; BOOL b = true; uint32_t u32 = 32; uint16_t u16 = 16; uint8_t u8 = 8; int32_t i32 = -32; int16_t i16 = -16; int8_t i8 = -8; test_enum te = test_b; sstrcpy(str, original); if (dir == PACKET_ENCODE) NETbeginEncode(0, 0); else NETbeginDecode(0); NETbool(&b); assert(b == true); NETuint32_t(&u32); assert(u32 == 32); NETuint16_t(&u16); assert(u16 == 16); NETuint8_t(&u8); assert(u8 == 8); NETint32_t(&i32); assert(i32 == -32); NETint16_t(&i16); assert(i16 == -16); NETint8_t(&i8); assert(i8 == -8); NETstring(str, sizeof(str)); assert(strncmp(str, original, sizeof(str) - 1) == 0); NETenum(&te); assert(te == test_b); }
void recvPlayerGameTime(NETQUEUE queue) { uint32_t latencyTicks = 0; uint32_t checkTime = 0; uint32_t checkCrc = 0; NETbeginDecode(queue, GAME_GAME_TIME); NETuint32_t(&latencyTicks); NETuint32_t(&checkTime); NETuint32_tLarge(&checkCrc); NETuint16_t(&wantedLatencies[queue.index]); NETend(); gameQueueTime[queue.index] = checkTime + latencyTicks * GAME_TICKS_PER_UPDATE; // gameTime when future messages shall be processed. gameQueueCheckTime[queue.index] = checkTime; gameQueueCheckCrc[queue.index] = checkCrc; if (!checkDebugSync(checkTime, checkCrc)) { crcError = true; if (NetPlay.players[queue.index].allocated) { NETsetPlayerConnectionStatus(CONNECTIONSTATUS_DESYNC, queue.index); } } if (updateReadyTime == 0 && checkPlayerGameTime(NET_ALL_PLAYERS)) { updateReadyTime = wzGetTicks(); // This is the time we were able to tick. } }
/// Does not read/write info->droidId! static void NETQueuedDroidInfo(QueuedDroidInfo *info) { NETuint8_t(&info->player); NETenum(&info->order); NETbool(&info->subType); if (info->subType) { NETuint32_t(&info->destId); NETenum(&info->destType); } else { NETuint32_t(&info->x); NETuint32_t(&info->y); } if (info->order == DORDER_BUILD || info->order == DORDER_LINEBUILD) { NETuint32_t(&info->structRef); NETuint16_t(&info->direction); } if (info->order == DORDER_LINEBUILD) { NETuint32_t(&info->x2); NETuint32_t(&info->y2); } }
// //////////////////////////////////////////////////////////////////////////// // INFORM others that a building has been started, and base plate should be put down. BOOL sendBuildStarted(STRUCTURE *psStruct, DROID *psDroid) { NETbeginEncode(NET_BUILD, NET_ALL_PLAYERS); // Who is building it NETuint8_t(&psDroid->player); // What they are building NETuint32_t(&psDroid->psTarStats->ref); // Where it is being built NETuint16_t(&psDroid->orderX); NETuint16_t(&psDroid->orderY); // The droid building it NETuint32_t(&psDroid->id); // The ID assigned to the structure being built NETuint32_t(&psStruct->id); // The droids order NETint32_t(&psDroid->order); if (psDroid->psTarget && psDroid->psTarget->type == OBJ_STRUCTURE) { // The ID of the droids target (== psStruct->id ?) NETuint32_t(&psDroid->psTarget->id); } else { NETnull(); } // Z coord NETint32_t(&psStruct->pos.z); return NETend(); }
/** Sends or receives a string to or from the current network package. * \param str When encoding a packet this is the (NUL-terminated string to * be sent in the current network package. When decoding this * is the buffer to decode the string from the network package * into. When decoding this string is guaranteed to be * NUL-terminated provided that this buffer is at least 1 byte * large. * \param maxlen The buffer size of \c str. For static buffers this means * sizeof(\c str), for dynamically allocated buffers this is * whatever number you passed to malloc(). * \note If while decoding \c maxlen is smaller than the actual length of the * string being decoded, the resulting string (in \c str) will be * truncated. */ BOOL NETstring(char *str, uint16_t maxlen) { /* * Strings sent over the network are prefixed with their length, sent as an * unsigned 16-bit integer. */ // Work out the length of the string if we are encoding uint16_t len = (NETgetPacketDir() == PACKET_ENCODE) ? strnlen1(str, maxlen) : 0; char *store; // Add/fetch the length from the packet NETuint16_t(&len); // Map store to the message buffer store = (char *) &NetMsg.body[NetMsg.size]; // Make sure there is enough data/space left in the packet if (len + NetMsg.size > sizeof(NetMsg.body) || !NetMsg.status) { return NetMsg.status = false; } if (NETgetPacketDir() == PACKET_ENCODE) { memcpy(store, str, len); } else if (NETgetPacketDir() == PACKET_DECODE) { // Truncate length if necessary if (len > maxlen) { debug(LOG_ERROR, "NETstring: Decoding packet type %d from %d, buffer size %u truncated at %u", NetMsg.type, NetMsg.source, len, maxlen); len = maxlen; } memcpy(str, store, len); // Guarantee NUL-termination str[len - 1] = '\0'; } // Increment the size of the message NetMsg.size += sizeof(len) + len; return true; }
void sendPlayerGameTime() { unsigned player; uint32_t latencyTicks = discreteChosenLatency / GAME_TICKS_PER_UPDATE; uint32_t checkTime = gameTime; uint32_t checkCrc = nextDebugSync(); for (player = 0; player < game.maxPlayers; ++player) { if (!myResponsibility(player) && whosResponsible(player) != realSelectedPlayer) { continue; } NETbeginEncode(NETgameQueue(player), GAME_GAME_TIME); NETuint32_t(&latencyTicks); NETuint32_t(&checkTime); NETuint32_tLarge(&checkCrc); NETuint16_t(&wantedLatency); NETend(); } }
/// Does not read/write info->droidId! static void NETQueuedDroidInfo(QueuedDroidInfo *info) { NETuint8_t(&info->player); NETenum(&info->subType); switch (info->subType) { case ObjOrder: case LocOrder: NETenum(&info->order); if (info->subType == ObjOrder) { NETuint32_t(&info->destId); NETenum(&info->destType); } else { NETauto(&info->pos); } if (info->order == DORDER_BUILD || info->order == DORDER_LINEBUILD) { NETuint32_t(&info->structRef); NETuint16_t(&info->direction); } if (info->order == DORDER_LINEBUILD) { NETauto(&info->pos2); } if (info->order == DORDER_BUILDMODULE) { NETauto(&info->index); } NETbool(&info->add); break; case SecondaryOrder: NETenum(&info->secOrder); NETenum(&info->secState); break; } }
BOOL NETRotation(Rotation *vp) { return (NETuint16_t(&vp->direction) && NETuint16_t(&vp->pitch) && NETuint16_t(&vp->roll)); }
// //////////////////////////////////////////////////////////////////////////// // put down a base plate and start droid building it! BOOL recvBuildStarted() { STRUCTURE_STATS *psStats; DROID *psDroid; UDWORD actionX,actionY; unsigned int typeIndex; uint8_t player; uint16_t x, y, z; int32_t order; uint32_t structRef, structId, targetId,droidID; NETbeginDecode(NET_BUILD); NETuint8_t(&player); NETuint32_t(&structRef); NETuint16_t(&x); NETuint16_t(&y); NETuint32_t(&droidID); NETuint32_t(&structId); NETint32_t(&order); NETuint32_t(&targetId); NETuint16_t(&z); NETend(); // Find structure target for (typeIndex = 0; typeIndex < numStructureStats && asStructureStats[typeIndex].ref != structRef; typeIndex++); psStats = &asStructureStats[typeIndex]; if (IdToDroid(droidID, player, &psDroid)) { // Tell the droid to go to where it needs to in order to build the struct if (getDroidDestination((BASE_STATS *) psStats, x, y, &actionX, &actionY)) { psDroid->order = order; if (psDroid->order == DORDER_LINEBUILD) { psDroid->order = DORDER_BUILD; } psDroid->orderX = x; psDroid->orderY = y; psDroid->psTarStats = (BASE_STATS *) psStats; if (targetId) { setDroidTarget(psDroid, IdToPointer(targetId, ANYPLAYER)); } else { setDroidTarget(psDroid, NULL); } if (IsStatExpansionModule(psStats)) { setUpBuildModule(psDroid); } else { droidStartBuild(psDroid); psDroid->action = DACTION_BUILD; } } // Sync IDs if (psDroid->psTarget) { ((STRUCTURE *) psDroid->psTarget)->id = structId; } } return true; }