Some refactoring of network code.
This commit is contained in:
parent
0a6e1760d5
commit
94f20ffea4
7 changed files with 610 additions and 435 deletions
|
@ -49,9 +49,6 @@ class ButtonStyle;
|
|||
extern void DrawUIButton(ButtonStyle *style, unsigned flags,
|
||||
int x, int y, const std::string &text);
|
||||
|
||||
/// Compare Local State <-> Server's state, force Update when changes
|
||||
extern void NetClientCheckLocalState();
|
||||
|
||||
/// Pre menu setup
|
||||
extern void PreMenuSetup();
|
||||
|
||||
|
|
|
@ -76,20 +76,14 @@ public:
|
|||
void Clear();
|
||||
static size_t Size() { return 4 + 2 + 2 + NetPlayerNameSize; }
|
||||
|
||||
void SetName(const char *name);
|
||||
|
||||
uint32_t Host; /// Host address
|
||||
uint16_t Port; /// Port on host
|
||||
uint16_t PlyNr; /// Player number
|
||||
char PlyName[NetPlayerNameSize]; /// Name of player
|
||||
};
|
||||
|
||||
/**
|
||||
** Connect state information of network systems active in current game.
|
||||
*/
|
||||
typedef struct _network_state_ {
|
||||
unsigned char State; /// Menu: ConnectState
|
||||
unsigned short MsgCnt; /// Menu: Counter for state msg of same type (detect unreachable)
|
||||
// Fill in here...
|
||||
} NetworkState;
|
||||
|
||||
/**
|
||||
** Multiplayer game setup menu state
|
||||
|
@ -99,27 +93,34 @@ class CServerSetup
|
|||
public:
|
||||
unsigned char *Serialize() const;
|
||||
void Deserialize(const unsigned char *p);
|
||||
static size_t Size() { return 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 * PlayerMax + 4 * PlayerMax + 4 * PlayerMax + 4 * PlayerMax; }
|
||||
static size_t Size() { return 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 * PlayerMax + 1 * PlayerMax + 1 * PlayerMax + 4 * PlayerMax; }
|
||||
void Clear() {
|
||||
ResourcesOption = UnitsOption = FogOfWar = RevealMap = TilesetSelection =
|
||||
GameTypeOption = Difficulty = MapRichness = 0;
|
||||
ResourcesOption = 0;
|
||||
UnitsOption = 0;
|
||||
FogOfWar = 0;
|
||||
RevealMap = 0;
|
||||
TilesetSelection = 0;
|
||||
GameTypeOption = 0;
|
||||
Difficulty = 0;
|
||||
MapRichness = 0;
|
||||
memset(CompOpt, 0, sizeof(CompOpt));
|
||||
memset(Ready, 0, sizeof(Ready));
|
||||
memset(Race, 0, sizeof(Race));
|
||||
memset(LastFrame, 0, sizeof(LastFrame));
|
||||
}
|
||||
|
||||
uint32_t ResourcesOption; /// Resources option
|
||||
uint32_t UnitsOption; /// Unit # option
|
||||
uint32_t FogOfWar; /// Fog of war option
|
||||
uint32_t RevealMap; /// Reveal all the map
|
||||
uint32_t TilesetSelection; /// Tileset select option
|
||||
uint32_t GameTypeOption; /// Game type option
|
||||
uint32_t Difficulty; /// Difficulty option
|
||||
uint32_t MapRichness; /// Map richness option
|
||||
uint32_t CompOpt[PlayerMax]; /// Free slot option selection {"Available", "Computer", "Closed" }
|
||||
uint32_t Ready[PlayerMax]; /// Client ready state
|
||||
uint32_t Race[PlayerMax]; /// Client race selection
|
||||
uint32_t LastFrame[PlayerMax]; /// Last message received
|
||||
uint8_t ResourcesOption; /// Resources option
|
||||
uint8_t UnitsOption; /// Unit # option
|
||||
uint8_t FogOfWar; /// Fog of war option
|
||||
uint8_t RevealMap; /// Reveal all the map
|
||||
uint8_t TilesetSelection; /// Tileset select option
|
||||
uint8_t GameTypeOption; /// Game type option
|
||||
uint8_t Difficulty; /// Difficulty option
|
||||
uint8_t MapRichness; /// Map richness option
|
||||
uint8_t CompOpt[PlayerMax]; /// Free slot option selection {"Available", "Computer", "Closed" }
|
||||
uint8_t Ready[PlayerMax]; /// Client ready state
|
||||
uint8_t Race[PlayerMax]; /// Client race selection
|
||||
uint32_t LastFrame[PlayerMax]; /// Last message received
|
||||
// Fill in here...
|
||||
};
|
||||
|
||||
|
@ -132,24 +133,25 @@ public:
|
|||
class CInitMessage
|
||||
{
|
||||
public:
|
||||
CInitMessage();
|
||||
unsigned char *Serialize() const;
|
||||
void Deserialize(const unsigned char *p);
|
||||
static size_t Size() { return 1 + 1 + 4 + 4 + 4 + 4 + 4 + 4 + 1 + 256 + CNetworkHost::Size() * PlayerMax + CServerSetup::Size(); }
|
||||
static size_t Size() { return 1 + 1 + 1 + 1 + 4 + 4 + 4 + 4 + 4 + 4 + std::max(256u, std::max(CNetworkHost::Size() * PlayerMax, CServerSetup::Size())); }
|
||||
|
||||
uint8_t Type; /// Init message type
|
||||
uint8_t SubType; /// Init message subtype
|
||||
int32_t Stratagus; /// Stratagus engine version
|
||||
int32_t Version; /// Network protocol version
|
||||
uint32_t ConfUID; /// Engine configuration UID (Checksum) FIXME: not available yet
|
||||
uint32_t MapUID; /// UID of map to play. FIXME: add MAP name, path, etc
|
||||
int32_t Lag; /// Lag time
|
||||
int32_t Updates; /// Update frequency
|
||||
uint8_t HostsCount; /// Number of hosts
|
||||
uint8_t Type; /// Init message type
|
||||
uint8_t SubType; /// Init message subtype
|
||||
uint8_t HostsCount; /// Number of hosts
|
||||
uint8_t padding; /// padding for alignment
|
||||
int32_t Stratagus; /// Stratagus engine version
|
||||
int32_t Version; /// Network protocol version
|
||||
uint32_t MapUID; /// UID of map to play. FIXME: add MAP name, path, etc
|
||||
int32_t Lag; /// Lag time
|
||||
int32_t Updates; /// Update frequency
|
||||
|
||||
union {
|
||||
CNetworkHost Hosts[PlayerMax]; /// Participant information
|
||||
char MapPath[256];
|
||||
CServerSetup State; /// Server Setup State information
|
||||
CServerSetup State; /// Server Setup State information
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -219,7 +221,6 @@ extern int HostsCount; /// Number of hosts.
|
|||
extern CNetworkHost Hosts[PlayerMax]; /// Host, port, and number of all players.
|
||||
|
||||
extern int NetConnectRunning; /// Network menu: Setup mode active
|
||||
extern NetworkState NetStates[PlayerMax]; /// Network menu: Server: Client Host states
|
||||
extern unsigned char NetLocalState; /// Network menu: Local Server/Client connect state
|
||||
extern int NetLocalHostsSlot; /// Network menu: Slot # in Hosts array of local client
|
||||
extern int NetLocalPlayerNumber; /// Player number of local client
|
||||
|
@ -231,6 +232,7 @@ extern CServerSetup LocalSetupState; /// Network menu: Multiplayer Client
|
|||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
extern int FindHostIndexBy(unsigned long ip, int port);
|
||||
extern void NetworkServerStartGame(); /// Server user has finally hit the start game button
|
||||
extern void NetworkGamePrepareGameSettings();
|
||||
extern void NetworkConnectSetupGame(); /// Assign Player slot, evaluate Setup state..
|
||||
|
@ -240,7 +242,7 @@ extern void NetworkExitClientConnect(); /// Terminate network connect state
|
|||
extern void NetworkInitServerConnect(int openslots); /// Setup network connect state machine for the server
|
||||
extern void NetworkExitServerConnect(); /// Terminate network connect state machine for the server
|
||||
extern int NetworkParseSetupEvent(const unsigned char *buf, int size, unsigned long host, int port); /// Parse a network connect event
|
||||
extern int NetworkSetupServerAddress(const std::string &serveraddr); /// Menu: Setup the server IP
|
||||
extern int NetworkSetupServerAddress(const std::string &serveraddr, int port); /// Menu: Setup the server IP
|
||||
extern void NetworkProcessClientRequest(); /// Menu Loop: Send out client request messages
|
||||
extern void NetworkProcessServerRequest(); /// Menu Loop: Send out server request messages
|
||||
extern void NetworkServerResyncClients(); /// Menu Loop: Server: Mark clients state to send stateinfo message
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -543,7 +543,7 @@ void InitNetwork1()
|
|||
const unsigned long myHost = NetResolveHost(buf);
|
||||
const int myPort = port;
|
||||
DebugPrint("My host:port %d.%d.%d.%d:%d\n" _C_
|
||||
NIPQUAD(ntohl(myHost)) _C_ ntohs(myPort));
|
||||
NIPQUAD(ntohl(myHost)) _C_ myPort);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -864,11 +864,8 @@ void NetworkEvent()
|
|||
unsigned char buf[1024];
|
||||
unsigned long host;
|
||||
int port;
|
||||
int i;
|
||||
if ((i = NetRecvUDP(NetworkFildes, &buf, sizeof(buf), &host, &port)) < 0) {
|
||||
//
|
||||
// Server or client gone?
|
||||
//
|
||||
int len = NetRecvUDP(NetworkFildes, &buf, sizeof(buf), &host, &port);
|
||||
if (len < 0) {
|
||||
DebugPrint("Server/Client gone?\n");
|
||||
// just hope for an automatic recover right now..
|
||||
NetworkInSync = 0;
|
||||
|
@ -881,31 +878,25 @@ void NetworkEvent()
|
|||
|
||||
// Setup messages
|
||||
if (NetConnectRunning) {
|
||||
if (NetworkParseSetupEvent(buf, i, host, port)) {
|
||||
if (NetworkParseSetupEvent(buf, len, host, port)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CNetworkPacket packet;
|
||||
int commands = packet.Deserialize(buf, i);
|
||||
int commands = packet.Deserialize(buf, len);
|
||||
if (commands < 0) {
|
||||
DebugPrint("Bad packet read\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < HostsCount; ++i) {
|
||||
if (Hosts[i].Host == host && Hosts[i].Port == port
|
||||
&& !PlayerQuit[Hosts[i].PlyNr]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == HostsCount) {
|
||||
const int index = FindHostIndexBy(host, port);
|
||||
if (index == -1 || PlayerQuit[Hosts[index].PlyNr]) {
|
||||
DebugPrint("Not a host in play: %d.%d.%d.%d:%d\n" _C_
|
||||
NIPQUAD(ntohl(host)) _C_ ntohs(port));
|
||||
return;
|
||||
}
|
||||
|
||||
const int player = Hosts[i].PlyNr;
|
||||
const int player = Hosts[index].PlyNr;
|
||||
|
||||
// In a normal packet there is a least sync, selection may not have that
|
||||
if (packet.Header.Type[0] == MessageSelection || commands == 0) {
|
||||
|
@ -914,13 +905,13 @@ void NetworkEvent()
|
|||
}
|
||||
|
||||
// Parse the packet commands.
|
||||
for (i = 0; i < commands; ++i) {
|
||||
const CNetworkCommand *nc = &packet.Command[i];
|
||||
for (int i = 0; i != commands; ++i) {
|
||||
const CNetworkCommand &nc = packet.Command[i];
|
||||
bool validCommand = false;
|
||||
|
||||
// Handle some messages.
|
||||
if (packet.Header.Type[i] == MessageQuit) {
|
||||
int playerNum = ntohs(nc->X);
|
||||
int playerNum = ntohs(nc.X);
|
||||
|
||||
if (playerNum >= 0 && playerNum < NumPlayers) {
|
||||
PlayerQuit[playerNum] = 1;
|
||||
|
@ -996,7 +987,7 @@ void NetworkEvent()
|
|||
case MessageCommandDismiss:
|
||||
// Fall through!
|
||||
default: {
|
||||
const unsigned int slot = ntohs(nc->Unit);
|
||||
const unsigned int slot = ntohs(nc.Unit);
|
||||
const CUnit *unit = slot < UnitManager.GetUsedSlotCount() ? &UnitManager.GetSlotUnit(slot) : NULL;
|
||||
|
||||
if (unit && (unit->Player->Index == player
|
||||
|
@ -1012,7 +1003,7 @@ void NetworkEvent()
|
|||
if (validCommand) {
|
||||
NetworkIn[packet.Header.Cycle][player][i].Time = n;
|
||||
NetworkIn[packet.Header.Cycle][player][i].Type = packet.Header.Type[i];
|
||||
NetworkIn[packet.Header.Cycle][player][i].Data = *nc;
|
||||
NetworkIn[packet.Header.Cycle][player][i].Data = nc;
|
||||
} else {
|
||||
SetMessage(_("%s sent bad command"), Players[player].Name.c_str());
|
||||
DebugPrint("%s sent bad command: 0x%x\n" _C_ Players[player].Name.c_str()
|
||||
|
@ -1020,7 +1011,7 @@ void NetworkEvent()
|
|||
}
|
||||
}
|
||||
|
||||
for (; i < MaxNetworkCommands; ++i) {
|
||||
for (int i = commands; i != MaxNetworkCommands; ++i) {
|
||||
NetworkIn[packet.Header.Cycle][player][i].Time = 0;
|
||||
}
|
||||
|
||||
|
@ -1067,11 +1058,12 @@ void NetworkChatMessage(const std::string &msg)
|
|||
if (IsNetworkGame()) {
|
||||
const char *cp = msg.c_str();
|
||||
size_t n = msg.size();
|
||||
while (n >= sizeof(char) * 7) {
|
||||
CNetworkChat *ncm = NULL;
|
||||
while (n >= sizeof(ncm->Text)) {
|
||||
CNetworkCommandQueue *ncq = AllocNCQ();
|
||||
MsgCommandsIn.push_back(ncq);
|
||||
ncq->Type = MessageChat;
|
||||
CNetworkChat *ncm = (CNetworkChat *)(&ncq->Data);
|
||||
ncm = (CNetworkChat *)(&ncq->Data);
|
||||
ncm->Player = ThisPlayer->Index;
|
||||
memcpy(ncm->Text, cp, sizeof(ncm->Text));
|
||||
cp += sizeof(ncm->Text);
|
||||
|
@ -1080,7 +1072,7 @@ void NetworkChatMessage(const std::string &msg)
|
|||
CNetworkCommandQueue *ncq = AllocNCQ();
|
||||
MsgCommandsIn.push_back(ncq);
|
||||
ncq->Type = MessageChatTerm;
|
||||
CNetworkChat *ncm = (CNetworkChat *)(&ncq->Data);
|
||||
ncm = (CNetworkChat *)(&ncq->Data);
|
||||
ncm->Player = ThisPlayer->Index;
|
||||
memcpy(ncm->Text, cp, n + 1); // see >= above :)
|
||||
}
|
||||
|
@ -1107,7 +1099,7 @@ static void ParseNetworkCommand_Chat(const CNetworkCommandQueue &ncq)
|
|||
const CNetworkChat &ncm = reinterpret_cast<const CNetworkChat &>(ncq.Data);
|
||||
int ply = ncm.Player;
|
||||
|
||||
if (NetMsgBufLen[ply] + sizeof(char) * 7 < 128) {
|
||||
if (NetMsgBufLen[ply] + sizeof(ncm.Text) < 128) {
|
||||
memcpy(NetMsgBuf[ply] + NetMsgBufLen[ply], ncm.Text, sizeof(ncm.Text));
|
||||
}
|
||||
NetMsgBufLen[ply] += sizeof(ncm.Text);
|
||||
|
|
|
@ -5,7 +5,7 @@ void ExitNetwork1(void);
|
|||
|
||||
bool IsNetworkGame();
|
||||
|
||||
int NetworkSetupServerAddress(const std::string serveraddr);
|
||||
int NetworkSetupServerAddress(const std::string serveraddr, int port = 0);
|
||||
void NetworkInitClientConnect(void);
|
||||
void NetworkInitServerConnect(int openslots);
|
||||
void NetworkServerStartGame(void);
|
||||
|
@ -16,16 +16,16 @@ void NetworkServerResyncClients(void);
|
|||
void NetworkDetachFromServer(void);
|
||||
|
||||
class CServerSetup {
|
||||
unsigned int ResourcesOption;
|
||||
unsigned int UnitsOption;
|
||||
unsigned int FogOfWar;
|
||||
unsigned int RevealMap;
|
||||
unsigned int GameTypeOption;
|
||||
unsigned int Difficulty;
|
||||
unsigned int MapRichness;
|
||||
unsigned CompOpt[PlayerMax];
|
||||
unsigned Ready[PlayerMax];
|
||||
unsigned Race[PlayerMax];
|
||||
unsigned char ResourcesOption;
|
||||
unsigned char UnitsOption;
|
||||
unsigned char FogOfWar;
|
||||
unsigned char RevealMap;
|
||||
unsigned char GameTypeOption;
|
||||
unsigned char Difficulty;
|
||||
unsigned char MapRichness;
|
||||
unsigned short CompOpt[PlayerMax]; // cannot use char since tolua interpret variable as string else.
|
||||
unsigned short Ready[PlayerMax]; // cannot use char since tolua interpret variable as string else.
|
||||
unsigned short Race[PlayerMax]; // cannot use char since tolua interpret variable as string else.
|
||||
unsigned long LastFrame[PlayerMax];
|
||||
};
|
||||
extern CServerSetup LocalSetupState;
|
||||
|
|
115
tests/network/test_netconnect.cpp
Normal file
115
tests/network/test_netconnect.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name test_net_lowlevel.cpp - The test file for net_lowlevel.cpp. */
|
||||
//
|
||||
// (c) Copyright 2013 by Joris Dauphin
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; only version 2 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
|
||||
#include <UnitTest++.h>
|
||||
|
||||
#include "stratagus.h"
|
||||
#include "netconnect.h"
|
||||
|
||||
|
||||
void FillCustomValue(CNetworkHost *obj)
|
||||
{
|
||||
obj->Host = 0x12345678;
|
||||
obj->Port = 0x9ABC;
|
||||
for (int i = 0; i != sizeof(CNetworkHost::PlyName); ++i) {
|
||||
obj->PlyName[i] = i + 1;
|
||||
}
|
||||
obj->PlyNr = 0xDEF0;
|
||||
}
|
||||
|
||||
void FillCustomValue(CServerSetup *obj)
|
||||
{
|
||||
obj->ResourcesOption = 42;
|
||||
obj->UnitsOption = 44;
|
||||
obj->FogOfWar = 46;
|
||||
obj->RevealMap = 48;
|
||||
obj->TilesetSelection = 50;
|
||||
obj->GameTypeOption = 52;
|
||||
obj->Difficulty = 54;
|
||||
obj->MapRichness = 56;
|
||||
for (int i = 0; i != PlayerMax; ++i) {
|
||||
obj->CompOpt[i] = i + 1;
|
||||
}
|
||||
for (int i = 0; i != PlayerMax; ++i) {
|
||||
obj->Ready[i] = i + 11;
|
||||
}
|
||||
for (int i = 0; i != PlayerMax; ++i) {
|
||||
obj->Race[i] = i + 21;
|
||||
}
|
||||
for (int i = 0; i != PlayerMax; ++i) {
|
||||
obj->LastFrame[i] = 0x22334455 + i * 0x01020304;
|
||||
}
|
||||
}
|
||||
|
||||
void FillCustomValue(CInitMessage *obj)
|
||||
{
|
||||
obj->Type = 0x22;
|
||||
obj->SubType = ICMHello;
|
||||
obj->HostsCount = 0x04;
|
||||
obj->padding = 0x33;
|
||||
obj->Stratagus = 0x12345678;
|
||||
obj->Version = 0x90ABCDEF;
|
||||
obj->MapUID = 0x09BADCFE;
|
||||
obj->Lag = 0x13245768;
|
||||
obj->Updates = 0x9A0BCEDF;
|
||||
// it is the biggest data size.
|
||||
for (int i = 0; i != PlayerMax; ++i) {
|
||||
FillCustomValue(&obj->u.Hosts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool CheckSerialization()
|
||||
{
|
||||
T obj1;
|
||||
|
||||
FillCustomValue(&obj1);
|
||||
const unsigned char *buffer = obj1.Serialize();
|
||||
|
||||
T obj2;
|
||||
obj2.Deserialize(buffer);
|
||||
bool res = memcmp(&obj1, &obj2, sizeof(T)) == 0;
|
||||
delete [] buffer;
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(CNetworkHost)
|
||||
{
|
||||
CHECK(CheckSerialization<CNetworkHost>());
|
||||
}
|
||||
|
||||
TEST(CServerSetup)
|
||||
{
|
||||
CHECK(CheckSerialization<CServerSetup>());
|
||||
}
|
||||
|
||||
TEST(CInitMessage)
|
||||
{
|
||||
CHECK(CheckSerialization<CInitMessage>());
|
||||
}
|
115
tests/network/test_network.cpp
Normal file
115
tests/network/test_network.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name test_net_lowlevel.cpp - The test file for net_lowlevel.cpp. */
|
||||
//
|
||||
// (c) Copyright 2013 by Joris Dauphin
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; only version 2 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
|
||||
#include <UnitTest++.h>
|
||||
|
||||
#include "stratagus.h"
|
||||
#include "network.h"
|
||||
|
||||
|
||||
void FillCustomValue(CNetworkCommand *obj)
|
||||
{
|
||||
obj->Dest = 0x1234;
|
||||
obj->Unit = 0x5678;
|
||||
obj->X = 0x9ABC;
|
||||
obj->Y = 0xDEF0;
|
||||
}
|
||||
|
||||
void FillCustomValue(CNetworkExtendedCommand *obj)
|
||||
{
|
||||
obj->ExtendedType = 11;
|
||||
obj->Arg1 = 22;
|
||||
obj->Arg2 = 0x1234;
|
||||
obj->Arg3 = 0x5678;
|
||||
obj->Arg4 = 0x9ABC;
|
||||
}
|
||||
|
||||
void FillCustomValue(CNetworkChat *obj)
|
||||
{
|
||||
obj->Player = 42;
|
||||
for (int i = 0; i != sizeof(obj->Text); ++i) {
|
||||
obj->Text[i] = 1 + i;
|
||||
}
|
||||
}
|
||||
|
||||
void FillCustomValue(CNetworkSelection *obj)
|
||||
{
|
||||
for (int i = 0; i != 4; ++i) {
|
||||
obj->Unit[i] = 0x1234 * i;
|
||||
}
|
||||
}
|
||||
|
||||
void FillCustomValue(CNetworkPacketHeader *obj)
|
||||
{
|
||||
obj->Cycle = 42;
|
||||
for (int i = 0; i != MaxNetworkCommands; ++i) {
|
||||
obj->Type[i] = 0x05 + i * 0x12;
|
||||
}
|
||||
}
|
||||
|
||||
// CNetworkPacket
|
||||
|
||||
template <typename T>
|
||||
bool CheckSerialization()
|
||||
{
|
||||
T obj1;
|
||||
|
||||
FillCustomValue(&obj1);
|
||||
unsigned char *buffer = new unsigned char [T::Size()];
|
||||
obj1.Serialize(buffer);
|
||||
|
||||
T obj2;
|
||||
obj2.Deserialize(buffer);
|
||||
bool res = memcmp(&obj1, &obj2, sizeof(T)) == 0;
|
||||
delete [] buffer;
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(CNetworkCommand)
|
||||
{
|
||||
CHECK(CheckSerialization<CNetworkCommand>());
|
||||
}
|
||||
TEST(CNetworkExtendedCommand)
|
||||
{
|
||||
CHECK(CheckSerialization<CNetworkExtendedCommand>());
|
||||
}
|
||||
TEST(CNetworkChat)
|
||||
{
|
||||
CHECK(CheckSerialization<CNetworkChat>());
|
||||
}
|
||||
#if 0
|
||||
TEST(CNetworkSelection)
|
||||
{
|
||||
CHECK(CheckSerialization<CNetworkSelection>());
|
||||
}
|
||||
#endif
|
||||
TEST(CNetworkPacketHeader)
|
||||
{
|
||||
CHECK(CheckSerialization<CNetworkPacketHeader>());
|
||||
}
|
Loading…
Reference in a new issue