Move network messages into its own file.

This commit is contained in:
joris 2013-03-24 14:57:58 +01:00
parent 0969b1cb27
commit 8c58c7b05e
10 changed files with 784 additions and 685 deletions

View file

@ -225,6 +225,7 @@ source_group(missile FILES ${missile_SRCS})
set(network_SRCS
src/network/commands.cpp
src/network/net_lowlevel.cpp
src/network/net_message.cpp
src/network/master.cpp
src/network/netconnect.cpp
src/network/network.cpp
@ -528,8 +529,9 @@ set(stratagus_generic_HDRS
src/include/missileconfig.h
src/include/movie.h
src/include/myendian.h
src/include/netconnect.h
src/include/net_lowlevel.h
src/include/net_message.h
src/include/netconnect.h
src/include/network.h
src/include/parameters.h
src/include/particle.h

340
src/include/net_message.h Normal file
View file

@ -0,0 +1,340 @@
// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
// \/ \/ \//_____/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// Stratagus - A free fantasy real time strategy game engine
//
/**@name net_message.h - The network message header file. */
//
// (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.
#ifndef NET_MESSAGE_H
#define NET_MESSAGE_H
//@{
#include <stdint.h>
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
/**
* Number of bytes in the name of a network player,
* including the terminating null character.
*/
#define NetPlayerNameSize 16
#define MaxNetworkCommands 9 /// Max Commands In A Packet
/**
** Network systems active in current game.
*/
class CNetworkHost
{
public:
const unsigned char *Serialize() const;
void Deserialize(const unsigned char *p);
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
};
/**
** Multiplayer game setup menu state
*/
class CServerSetup
{
public:
const unsigned char *Serialize() const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 * PlayerMax + 1 * PlayerMax + 1 * PlayerMax; }
void Clear() {
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));
}
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
// Fill in here...
};
/**
** Network init config message subtypes (menu state machine).
*/
enum _ic_message_subtype_ {
ICMHello, /// Client Request
ICMConfig, /// Setup message configure clients
ICMEngineMismatch, /// Stratagus engine version doesn't match
ICMProtocolMismatch, /// Network protocol version doesn't match
ICMEngineConfMismatch, /// Engine configuration isn't identical
ICMMapUidMismatch, /// MAP UID doesn't match
ICMGameFull, /// No player slots available
ICMWelcome, /// Acknowledge for new client connections
ICMWaiting, /// Client has received Welcome and is waiting for Map/State
ICMMap, /// MapInfo (and Mapinfo Ack)
ICMState, /// StateInfo
ICMResync, /// Ack StateInfo change
ICMServerQuit, /// Server has quit game
ICMGoodBye, /// Client wants to leave game
ICMSeeYou, /// Client has left game
ICMGo, /// Client is ready to run
ICMAYT, /// Server asks are you there
ICMIAH /// Client answers I am here
};
/**
** Network init message.
**
** @todo Transfering the same data in each message is waste of bandwidth.
** I mean the versions and the UID ...
*/
class CInitMessage
{
public:
CInitMessage();
const unsigned char *Serialize() const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 1 + 1 + 1 + 4 + 4 + 4 + 4 + 4 + 4 + std::max<size_t>(256u, std::max(CNetworkHost::Size() * PlayerMax, CServerSetup::Size())); }
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
} u;
};
/**
** Network message types.
**
** @todo cleanup the message types.
*/
enum _message_type_ {
MessageNone, /// When Nothing Is Happening
MessageInitHello, /// Start connection
MessageInitReply, /// Connection reply
MessageInitConfig, /// Setup message configure clients
MessageSync, /// Heart beat
MessageSelection, /// Update a Selection from Team Player
MessageQuit, /// Quit game
MessageQuitAck, /// Quit reply - UNUSED YET - Protocol Version 2 - Reserved for menus
MessageResend, /// Resend message
MessageChat, /// Chat message
MessageChatTerm, /// Chat message termination - Protocol Version 2
MessageCommandStop, /// Unit command stop
MessageCommandStand, /// Unit command stand ground
MessageCommandDefend, /// Unit command defend
MessageCommandFollow, /// Unit command follow
MessageCommandMove, /// Unit command move
MessageCommandRepair, /// Unit command repair
MessageCommandAutoRepair, /// Unit command autorepair
MessageCommandAttack, /// Unit command attack
MessageCommandGround, /// Unit command attack ground
MessageCommandPatrol, /// Unit command patrol
MessageCommandBoard, /// Unit command board
MessageCommandUnload, /// Unit command unload
MessageCommandBuild, /// Unit command build building
MessageCommandDismiss, /// Unit command dismiss unit
MessageCommandResourceLoc, /// Unit command resource location
MessageCommandResource, /// Unit command resource
MessageCommandReturn, /// Unit command return goods
MessageCommandTrain, /// Unit command train
MessageCommandCancelTrain, /// Unit command cancel training
MessageCommandUpgrade, /// Unit command upgrade
MessageCommandCancelUpgrade, /// Unit command cancel upgrade
MessageCommandResearch, /// Unit command research
MessageCommandCancelResearch, /// Unit command cancel research
MessageExtendedCommand, /// Command is the next byte
// ATTN: __MUST__ be last due to spellid encoding!!!
MessageCommandSpellCast /// Unit command spell cast
};
/**
** Network extended message types.
*/
enum _extended_message_type_ {
ExtendedMessageDiplomacy, /// Change diplomacy
ExtendedMessageSharedVision /// Change shared vision
};
/**
** Network command message.
*/
class CNetworkCommand
{
public:
CNetworkCommand() : Unit(0), X(0), Y(0), Dest(0) {}
void Clear() { this->Unit = this->X = this->Y = this->Dest = 0; }
void Serialize(unsigned char *p) const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 2 + 2 + 2 + 2; }
uint16_t Unit; /// Command for unit
uint16_t X; /// Map position X
uint16_t Y; /// Map position Y
uint16_t Dest; /// Destination unit
};
/**
** Extended network command message.
*/
class CNetworkExtendedCommand
{
public:
CNetworkExtendedCommand() : ExtendedType(0), Arg1(0), Arg2(0), Arg3(0), Arg4(0) {}
void Serialize(unsigned char *p) const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 1 + 2 + 2 + 2; }
uint8_t ExtendedType; /// Extended network command type
uint8_t Arg1; /// Argument 1
uint16_t Arg2; /// Argument 2
uint16_t Arg3; /// Argument 3
uint16_t Arg4; /// Argument 4
};
/**
** Network chat message.
*/
class CNetworkChat
{
public:
CNetworkChat() {
Player = 0;
memset(Text, 0, sizeof(Text));
}
void Serialize(unsigned char *p) const ;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 7; }
uint8_t Player; /// Sending player
char Text[7]; /// Message bytes
};
/**
** Network Selection Update
*/
class CNetworkSelection
{
public:
CNetworkSelection() {
memset(Unit, 0, sizeof(Unit));
}
void Serialize(unsigned char *p) const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 2 * 4; }
uint16_t Unit[4]; /// Selection Units
};
/**
** Network packet header.
**
** Header for the packet.
*/
class CNetworkPacketHeader
{
public:
CNetworkPacketHeader() {
Cycle = 0;
memset(Type, 0, sizeof(Type));
}
void Serialize(unsigned char *p) const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 1 * MaxNetworkCommands; }
uint8_t Cycle; /// Destination game cycle
uint8_t Type[MaxNetworkCommands]; /// Commands in packet
};
/**
** Network packet.
**
** This is sent over the network.
*/
class CNetworkPacket
{
public:
unsigned char *Serialize(int numcommands) const;
int Deserialize(const unsigned char *p, unsigned int len);
static size_t Size(int numcommands) {
return CNetworkPacketHeader::Size() + numcommands * CNetworkCommand::Size();
}
CNetworkPacketHeader Header; /// Packet Header Info
CNetworkCommand Command[MaxNetworkCommands];
};
//@}
#endif // !NET_MESSAGE_H

View file

@ -32,6 +32,7 @@
//@{
#include <stdint.h>
#include "net_message.h"
/*----------------------------------------------------------------------------
-- Defines
@ -57,130 +58,6 @@
-- Declarations
----------------------------------------------------------------------------*/
/**
* Number of bytes in the name of a network player,
* including the terminating null character.
*/
#define NetPlayerNameSize 16
/**
** Network systems active in current game.
*/
class CNetworkHost
{
public:
const unsigned char *Serialize() const;
void Deserialize(const unsigned char *p);
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
};
/**
** Multiplayer game setup menu state
*/
class CServerSetup
{
public:
const unsigned char *Serialize() const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 * PlayerMax + 1 * PlayerMax + 1 * PlayerMax; }
void Clear() {
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));
}
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
// Fill in here...
};
/**
** Network init message.
**
** @todo Transfering the same data in each message is waste of bandwidth.
** I mean the versions and the UID ...
*/
class CInitMessage
{
public:
CInitMessage();
const unsigned char *Serialize() const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 1 + 1 + 1 + 4 + 4 + 4 + 4 + 4 + 4 + std::max<size_t>(256u, std::max(CNetworkHost::Size() * PlayerMax, CServerSetup::Size())); }
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
} u;
};
/**
** Network init config message subtypes (menu state machine).
*/
enum _ic_message_subtype_ {
ICMHello, /// Client Request
ICMConfig, /// Setup message configure clients
ICMEngineMismatch, /// Stratagus engine version doesn't match
ICMProtocolMismatch, /// Network protocol version doesn't match
ICMEngineConfMismatch, /// Engine configuration isn't identical
ICMMapUidMismatch, /// MAP UID doesn't match
ICMGameFull, /// No player slots available
ICMWelcome, /// Acknowledge for new client connections
ICMWaiting, /// Client has received Welcome and is waiting for Map/State
ICMMap, /// MapInfo (and Mapinfo Ack)
ICMState, /// StateInfo
ICMResync, /// Ack StateInfo change
ICMServerQuit, /// Server has quit game
ICMGoodBye, /// Client wants to leave game
ICMSeeYou, /// Client has left game
ICMGo, /// Client is ready to run
ICMAYT, /// Server asks are you there
ICMIAH /// Client answers I am here
};
/**
** Network Client connect states
*/
@ -210,8 +87,6 @@ enum _net_client_con_state_ {
----------------------------------------------------------------------------*/
extern int NetPlayers; /// Network players
extern char *NetworkAddr; /// Local network address to use
extern int NetworkPort; /// Local network port to use
extern int HostsCount; /// Number of hosts.
extern CNetworkHost Hosts[PlayerMax]; /// Host, port, and number of all players.

View file

@ -42,10 +42,10 @@
-- Defines
----------------------------------------------------------------------------*/
#define MaxNetworkCommands 9 /// Max Commands In A Packet
#define IsNetworkGame() (NetworkFildes != (Socket)-1)
#define NetworkDefaultPort 6660 /// Default communication port
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
@ -53,191 +53,12 @@
class CUnit;
class CUnitType;
/**
** Network message types.
**
** @todo cleanup the message types.
*/
enum _message_type_ {
MessageNone, /// When Nothing Is Happening
MessageInitHello, /// Start connection
MessageInitReply, /// Connection reply
MessageInitConfig, /// Setup message configure clients
MessageSync, /// Heart beat
MessageSelection, /// Update a Selection from Team Player
MessageQuit, /// Quit game
MessageQuitAck, /// Quit reply - UNUSED YET - Protocol Version 2 - Reserved for menus
MessageResend, /// Resend message
MessageChat, /// Chat message
MessageChatTerm, /// Chat message termination - Protocol Version 2
MessageCommandStop, /// Unit command stop
MessageCommandStand, /// Unit command stand ground
MessageCommandDefend, /// Unit command defend
MessageCommandFollow, /// Unit command follow
MessageCommandMove, /// Unit command move
MessageCommandRepair, /// Unit command repair
MessageCommandAutoRepair, /// Unit command autorepair
MessageCommandAttack, /// Unit command attack
MessageCommandGround, /// Unit command attack ground
MessageCommandPatrol, /// Unit command patrol
MessageCommandBoard, /// Unit command board
MessageCommandUnload, /// Unit command unload
MessageCommandBuild, /// Unit command build building
MessageCommandDismiss, /// Unit command dismiss unit
MessageCommandResourceLoc, /// Unit command resource location
MessageCommandResource, /// Unit command resource
MessageCommandReturn, /// Unit command return goods
MessageCommandTrain, /// Unit command train
MessageCommandCancelTrain, /// Unit command cancel training
MessageCommandUpgrade, /// Unit command upgrade
MessageCommandCancelUpgrade, /// Unit command cancel upgrade
MessageCommandResearch, /// Unit command research
MessageCommandCancelResearch, /// Unit command cancel research
MessageExtendedCommand, /// Command is the next byte
// ATTN: __MUST__ be last due to spellid encoding!!!
MessageCommandSpellCast /// Unit command spell cast
};
/**
** Network extended message types.
*/
enum _extended_message_type_ {
ExtendedMessageDiplomacy, /// Change diplomacy
ExtendedMessageSharedVision /// Change shared vision
};
/**
** Network command message.
*/
class CNetworkCommand
{
public:
CNetworkCommand() : Unit(0), X(0), Y(0), Dest(0) {}
void Clear() { this->Unit = this->X = this->Y = this->Dest = 0; }
void Serialize(unsigned char *p) const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 2 + 2 + 2 + 2; }
uint16_t Unit; /// Command for unit
uint16_t X; /// Map position X
uint16_t Y; /// Map position Y
uint16_t Dest; /// Destination unit
};
/**
** Extended network command message.
*/
class CNetworkExtendedCommand
{
public:
CNetworkExtendedCommand() : ExtendedType(0), Arg1(0), Arg2(0), Arg3(0), Arg4(0) {}
void Serialize(unsigned char *p) const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 1 + 2 + 2 + 2; }
uint8_t ExtendedType; /// Extended network command type
uint8_t Arg1; /// Argument 1
uint16_t Arg2; /// Argument 2
uint16_t Arg3; /// Argument 3
uint16_t Arg4; /// Argument 4
};
/**
** Network chat message.
*/
class CNetworkChat
{
public:
CNetworkChat() {
Player = 0;
memset(Text, 0, sizeof(Text));
}
void Serialize(unsigned char *p) const ;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 7; }
uint8_t Player; /// Sending player
char Text[7]; /// Message bytes
};
/**
** Network Selection Info
*/
typedef struct _network_selection_header_ {
unsigned NumberSent : 6; /// New Number Selected
unsigned Add : 1; /// Adding to Selection
unsigned Remove : 1; /// Removing from Selection
unsigned char Type[MaxNetworkCommands]; /// Command
} NetworkSelectionHeader;
/**
** Network Selection Update
*/
class CNetworkSelection
{
public:
CNetworkSelection() {
memset(Unit, 0, sizeof(Unit));
}
void Serialize(unsigned char *p) const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 2 * 4; }
uint16_t Unit[4]; /// Selection Units
};
/**
** Network packet header.
**
** Header for the packet.
*/
class CNetworkPacketHeader
{
public:
CNetworkPacketHeader() {
Cycle = 0;
memset(Type, 0, sizeof(Type));
}
void Serialize(unsigned char *p) const;
void Deserialize(const unsigned char *p);
static size_t Size() { return 1 + 1 * MaxNetworkCommands; }
uint8_t Cycle; /// Destination game cycle
uint8_t Type[MaxNetworkCommands]; /// Commands in packet
};
/**
** Network packet.
**
** This is sent over the network.
*/
class CNetworkPacket
{
public:
unsigned char *Serialize(int numcommands) const;
int Deserialize(const unsigned char *p, unsigned int len);
static size_t Size(int numcommands) {
return CNetworkPacketHeader::Size() + numcommands * CNetworkCommand::Size();
}
CNetworkPacketHeader Header; /// Packet Header Info
CNetworkCommand Command[MaxNetworkCommands];
};
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
extern char *NetworkAddr; /// Local network address to use
extern int NetworkPort; /// Local network port to use
extern Socket NetworkFildes; /// Network file descriptor
extern int NetworkInSync; /// Network is in sync
extern int NetworkUpdates; /// Network update each # game cycles

View file

@ -34,14 +34,17 @@
----------------------------------------------------------------------------*/
#include "stratagus.h"
#include "commands.h"
#include "actions.h"
#include "net_message.h"
#include "network.h"
#include "replay.h"
#include "spells.h"
#include "unit.h"
#include "unit_manager.h"
#include "unittype.h"
#include "actions.h"
#include "network.h"
#include "spells.h"
#include "replay.h"
/*----------------------------------------------------------------------------
-- Functions

398
src/network/net_message.cpp Normal file
View file

@ -0,0 +1,398 @@
// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
// \/ \/ \//_____/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// Stratagus - A free fantasy real time strategy game engine
//
/**@name net_message.cpp - The network message code. */
//
// (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.
//
//@{
//----------------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------------
#include "stratagus.h"
#include "net_message.h"
#include "net_lowlevel.h"
#include "netconnect.h"
#include "network.h"
#include "version.h"
//
// CNetworkHost
//
const unsigned char *CNetworkHost::Serialize() const
{
unsigned char *buf = new unsigned char[CNetworkHost::Size()];
unsigned char *p = buf;
*(uint32_t *)p = htonl(this->Host);
p += 4;
*(uint16_t *)p = htons(this->Port);
p += 2;
*(uint16_t *)p = htons(this->PlyNr);
p += 2;
memcpy(p, this->PlyName, sizeof(this->PlyName));
return buf;
}
void CNetworkHost::Deserialize(const unsigned char *p)
{
this->Host = ntohl(*(uint32_t *)p);
p += 4;
this->Port = ntohs(*(uint16_t *)p);
p += 2;
this->PlyNr = ntohs(*(uint16_t *)p);
p += 2;
memcpy(this->PlyName, p, sizeof(this->PlyName));
}
void CNetworkHost::Clear()
{
this->Host = 0;
this->Port = 0;
this->PlyNr = 0;
memset(this->PlyName, 0, sizeof(this->PlyName));
}
void CNetworkHost::SetName(const char *name)
{
strncpy_s(this->PlyName, sizeof(this->PlyName), name, _TRUNCATE);
}
//
// CServerSetup
//
const unsigned char *CServerSetup::Serialize() const
{
unsigned char *buf = new unsigned char[CServerSetup::Size()];
unsigned char *p = buf;
*p++ = this->ResourcesOption;
*p++ = this->UnitsOption;
*p++ = this->FogOfWar;
*p++ = this->RevealMap;
*p++ = this->TilesetSelection;
*p++ = this->GameTypeOption;
*p++ = this->Difficulty;
*p++ = this->MapRichness;
for (int i = 0; i < PlayerMax; ++i) {
*p++ = this->CompOpt[i];
}
for (int i = 0; i < PlayerMax; ++i) {
*p++ = this->Ready[i];
}
for (int i = 0; i < PlayerMax; ++i) {
*p++ = this->Race[i];
}
return buf;
}
void CServerSetup::Deserialize(const unsigned char *p)
{
this->ResourcesOption = *p++;
this->UnitsOption = *p++;
this->FogOfWar = *p++;
this->RevealMap = *p++;
this->TilesetSelection = *p++;
this->GameTypeOption = *p++;
this->Difficulty = *p++;
this->MapRichness = *p++;
for (int i = 0; i < PlayerMax; ++i) {
this->CompOpt[i] = *p++;
}
for (int i = 0; i < PlayerMax; ++i) {
this->Ready[i] = *p++;
}
for (int i = 0; i < PlayerMax; ++i) {
this->Race[i] = *p++;
}
}
//
// CInitMessage
//
CInitMessage::CInitMessage()
{
memset(this, 0, sizeof(CInitMessage));
this->Stratagus = StratagusVersion;
this->Version = NetworkProtocolVersion;
this->Lag = NetworkLag;
this->Updates = NetworkUpdates;
}
const unsigned char *CInitMessage::Serialize() const
{
unsigned char *buf = new unsigned char[CInitMessage::Size()];
unsigned char *p = buf;
*p++ = this->Type;
*p++ = this->SubType;
*p++ = this->HostsCount;
*p++ = this->padding;
*(int32_t *)p = htonl(this->Stratagus);
p += 4;
*(int32_t *)p = htonl(this->Version);
p += 4;
*(uint32_t *)p = htonl(this->MapUID);
p += 4;
*(int32_t *)p = htonl(this->Lag);
p += 4;
*(int32_t *)p = htonl(this->Updates);
p += 4;
switch (this->SubType) {
case ICMHello:
case ICMConfig:
case ICMWelcome:
case ICMResync:
case ICMGo:
for (int i = 0; i < PlayerMax; ++i) {
const unsigned char *x = this->u.Hosts[i].Serialize();
memcpy(p, x, CNetworkHost::Size());
p += CNetworkHost::Size();
delete[] x;
}
break;
case ICMMap:
memcpy(p, this->u.MapPath, sizeof(this->u.MapPath));
p += sizeof(this->u.MapPath);
break;
case ICMState: {
const unsigned char *x = this->u.State.Serialize();
memcpy(p, x, CServerSetup::Size());
p += CServerSetup::Size();
delete[] x;
break;
}
}
return buf;
}
void CInitMessage::Deserialize(const unsigned char *p)
{
this->Type = *p++;
this->SubType = *p++;
this->HostsCount = *p++;
this->padding = *p++;
this->Stratagus = ntohl(*(int32_t *)p);
p += 4;
this->Version = ntohl(*(int32_t *)p);
p += 4;
this->MapUID = ntohl(*(uint32_t *)p);
p += 4;
this->Lag = ntohl(*(int32_t *)p);
p += 4;
this->Updates = ntohl(*(int32_t *)p);
p += 4;
switch (this->SubType) {
case ICMHello:
case ICMConfig:
case ICMWelcome:
case ICMResync:
case ICMGo:
for (int i = 0; i < PlayerMax; ++i) {
this->u.Hosts[i].Deserialize(p);
p += CNetworkHost::Size();
}
break;
case ICMMap:
memcpy(this->u.MapPath, p, sizeof(this->u.MapPath));
p += sizeof(this->u.MapPath);
break;
case ICMState:
this->u.State.Deserialize(p);
p += CServerSetup::Size();
break;
}
}
//
// CNetworkCommand
//
void CNetworkCommand::Serialize(unsigned char *p) const
{
*(uint16_t *)p = this->Unit;
p += 2;
*(uint16_t *)p = this->X;
p += 2;
*(uint16_t *)p = this->Y;
p += 2;
*(uint16_t *)p = this->Dest;
p += 2;
}
void CNetworkCommand::Deserialize(const unsigned char *p)
{
this->Unit = *(uint16_t *)p;
p += 2;
this->X = *(uint16_t *)p;
p += 2;
this->Y = *(uint16_t *)p;
p += 2;
this->Dest = *(uint16_t *)p;
p += 2;
}
//
// CNetworkExtendedCommand
//
void CNetworkExtendedCommand::Serialize(unsigned char *p) const
{
*p++ = this->ExtendedType;
*p++ = this->Arg1;
*(uint16_t *)p = this->Arg2;
p += 2;
*(uint16_t *)p = this->Arg3;
p += 2;
*(uint16_t *)p = this->Arg4;
p += 2;
}
void CNetworkExtendedCommand::Deserialize(const unsigned char *p)
{
this->ExtendedType = *p++;
this->Arg1 = *p++;
this->Arg2 = *(uint16_t *)p;
p += 2;
this->Arg3 = *(uint16_t *)p;
p += 2;
this->Arg4 = *(uint16_t *)p;
p += 2;
}
//
// CNetworkChat
//
void CNetworkChat::Serialize(unsigned char *p) const
{
*p++ = this->Player;
memcpy(p, this->Text, 7);
p += 7;
}
void CNetworkChat::Deserialize(const unsigned char *p)
{
this->Player = *p++;
memcpy(this->Text, p, 7);
p += 7;
}
//
// CNetworkPacketHeader
//
void CNetworkPacketHeader::Serialize(unsigned char *p) const
{
*p++ = this->Cycle;
for (int i = 0; i < MaxNetworkCommands; ++i) {
*p++ = this->Type[i];
}
}
void CNetworkPacketHeader::Deserialize(const unsigned char *p)
{
this->Cycle = *p++;
for (int i = 0; i < MaxNetworkCommands; ++i) {
this->Type[i] = *p++;
}
}
//
// CNetworkPacket
//
unsigned char *CNetworkPacket::Serialize(int numcommands) const
{
unsigned char *buf = new unsigned char[CNetworkPacket::Size(numcommands)];
unsigned char *p = buf;
this->Header.Serialize(p);
p += CNetworkPacketHeader::Size();
for (int i = 0; i < numcommands; ++i) {
if (this->Header.Type[i] == MessageExtendedCommand) {
((CNetworkExtendedCommand *)&this->Command[i])->Serialize(p);
} else if (this->Header.Type[i] == MessageChat) {
((CNetworkChat *)&this->Command[i])->Serialize(p);
} else {
this->Command[i].Serialize(p);
}
p += CNetworkCommand::Size();
}
return buf;
}
int CNetworkPacket::Deserialize(const unsigned char *p, unsigned int len)
{
// check min and max size
if (len < CNetworkPacket::Size(1)
|| len > CNetworkPacket::Size(MaxNetworkCommands)) {
return -1;
}
// can't have partial commands
len -= CNetworkPacketHeader::Size();
if ((len / CNetworkCommand::Size()) * CNetworkCommand::Size() != len) {
return -1;
}
this->Header.Deserialize(p);
p += CNetworkPacketHeader::Size();
int commands = len / CNetworkCommand::Size();
for (int i = 0; i < commands; ++i) {
if (this->Header.Type[i] == MessageExtendedCommand) {
((CNetworkExtendedCommand *)&this->Command[i])->Deserialize(p);
} else if (this->Header.Type[i] == MessageChat) {
((CNetworkChat *)&this->Command[i])->Deserialize(p);
} else {
this->Command[i].Deserialize(p);
}
p += CNetworkCommand::Size();
}
return commands;
}
//@}

View file

@ -53,8 +53,6 @@
// Declaration
//----------------------------------------------------------------------------
#define NetworkDefaultPort 6660 /// Default communication port
// received nothing from client for xx frames?
#define CLIENT_LIVE_BEAT 60
#define CLIENT_IS_DEAD 300
@ -81,9 +79,6 @@ struct NetworkState
// Variables
//----------------------------------------------------------------------------
char *NetworkAddr = NULL; /// Local network address to use
int NetworkPort = NetworkDefaultPort; /// Local network port to use
int HostsCount; /// Number of hosts.
CNetworkHost Hosts[PlayerMax]; /// Host and ports of all players.
@ -160,210 +155,12 @@ private:
unsigned long serverIP; /// IP of server to join
int serverPort; /// Server network port to use
NetworkState LocalNetState;
unsigned char LastStateMsgType; /// Subtype of last InitConfig message sent
unsigned char lastMsgTypeSent; /// Subtype of last InitConfig message sent
};
static CServer Server;
static CClient Client;
//
// CNetworkHost
//
const unsigned char *CNetworkHost::Serialize() const
{
unsigned char *buf = new unsigned char[CNetworkHost::Size()];
unsigned char *p = buf;
*(uint32_t *)p = htonl(this->Host);
p += 4;
*(uint16_t *)p = htons(this->Port);
p += 2;
*(uint16_t *)p = htons(this->PlyNr);
p += 2;
memcpy(p, this->PlyName, sizeof(this->PlyName));
return buf;
}
void CNetworkHost::Deserialize(const unsigned char *p)
{
this->Host = ntohl(*(uint32_t *)p);
p += 4;
this->Port = ntohs(*(uint16_t *)p);
p += 2;
this->PlyNr = ntohs(*(uint16_t *)p);
p += 2;
memcpy(this->PlyName, p, sizeof(this->PlyName));
}
void CNetworkHost::Clear()
{
this->Host = 0;
this->Port = 0;
this->PlyNr = 0;
memset(this->PlyName, 0, sizeof(this->PlyName));
}
void CNetworkHost::SetName(const char *name)
{
strncpy_s(this->PlyName, sizeof(this->PlyName), name, _TRUNCATE);
}
//
// CServerSetup
//
const unsigned char *CServerSetup::Serialize() const
{
unsigned char *buf = new unsigned char[CServerSetup::Size()];
unsigned char *p = buf;
*p++ = this->ResourcesOption;
*p++ = this->UnitsOption;
*p++ = this->FogOfWar;
*p++ = this->RevealMap;
*p++ = this->TilesetSelection;
*p++ = this->GameTypeOption;
*p++ = this->Difficulty;
*p++ = this->MapRichness;
for (int i = 0; i < PlayerMax; ++i) {
*p++ = this->CompOpt[i];
}
for (int i = 0; i < PlayerMax; ++i) {
*p++ = this->Ready[i];
}
for (int i = 0; i < PlayerMax; ++i) {
*p++ = this->Race[i];
}
return buf;
}
void CServerSetup::Deserialize(const unsigned char *p)
{
this->ResourcesOption = *p++;
this->UnitsOption = *p++;
this->FogOfWar = *p++;
this->RevealMap = *p++;
this->TilesetSelection = *p++;
this->GameTypeOption = *p++;
this->Difficulty = *p++;
this->MapRichness = *p++;
for (int i = 0; i < PlayerMax; ++i) {
this->CompOpt[i] = *p++;
}
for (int i = 0; i < PlayerMax; ++i) {
this->Ready[i] = *p++;
}
for (int i = 0; i < PlayerMax; ++i) {
this->Race[i] = *p++;
}
}
//
// CInitMessage
//
CInitMessage::CInitMessage()
{
memset(this, 0, sizeof(CInitMessage));
this->Stratagus = StratagusVersion;
this->Version = NetworkProtocolVersion;
this->Lag = NetworkLag;
this->Updates = NetworkUpdates;
}
const unsigned char *CInitMessage::Serialize() const
{
unsigned char *buf = new unsigned char[CInitMessage::Size()];
unsigned char *p = buf;
*p++ = this->Type;
*p++ = this->SubType;
*p++ = this->HostsCount;
*p++ = this->padding;
*(int32_t *)p = htonl(this->Stratagus);
p += 4;
*(int32_t *)p = htonl(this->Version);
p += 4;
*(uint32_t *)p = htonl(this->MapUID);
p += 4;
*(int32_t *)p = htonl(this->Lag);
p += 4;
*(int32_t *)p = htonl(this->Updates);
p += 4;
switch (this->SubType) {
case ICMHello:
case ICMConfig:
case ICMWelcome:
case ICMResync:
case ICMGo:
for (int i = 0; i < PlayerMax; ++i) {
const unsigned char *x = this->u.Hosts[i].Serialize();
memcpy(p, x, CNetworkHost::Size());
p += CNetworkHost::Size();
delete[] x;
}
break;
case ICMMap:
memcpy(p, this->u.MapPath, sizeof(this->u.MapPath));
p += sizeof(this->u.MapPath);
break;
case ICMState: {
const unsigned char *x = this->u.State.Serialize();
memcpy(p, x, CServerSetup::Size());
p += CServerSetup::Size();
delete[] x;
break;
}
}
return buf;
}
void CInitMessage::Deserialize(const unsigned char *p)
{
this->Type = *p++;
this->SubType = *p++;
this->HostsCount = *p++;
this->padding = *p++;
this->Stratagus = ntohl(*(int32_t *)p);
p += 4;
this->Version = ntohl(*(int32_t *)p);
p += 4;
this->MapUID = ntohl(*(uint32_t *)p);
p += 4;
this->Lag = ntohl(*(int32_t *)p);
p += 4;
this->Updates = ntohl(*(int32_t *)p);
p += 4;
switch (this->SubType) {
case ICMHello:
case ICMConfig:
case ICMWelcome:
case ICMResync:
case ICMGo:
for (int i = 0; i < PlayerMax; ++i) {
this->u.Hosts[i].Deserialize(p);
p += CNetworkHost::Size();
}
break;
case ICMMap:
memcpy(this->u.MapPath, p, sizeof(this->u.MapPath));
p += sizeof(this->u.MapPath);
break;
case ICMState:
this->u.State.Deserialize(p);
p += CServerSetup::Size();
break;
}
}
//
// CClient
//
@ -456,11 +253,11 @@ void CClient::NetworkSendRateLimitedClientMessage(const CInitMessage &msg, unsig
const unsigned long now = GetTicks();
if (now - LocalNetState.LastFrame >= msecs) {
LocalNetState.LastFrame = now;
if (msg.SubType == LastStateMsgType) {
if (msg.SubType == lastMsgTypeSent) {
++LocalNetState.MsgCnt;
} else {
LocalNetState.MsgCnt = 0;
LastStateMsgType = msg.SubType;
lastMsgTypeSent = msg.SubType;
}
const int n = NetworkSendICMessage(serverIP, serverPort, msg);
UNUSED(n); // not used in release
@ -491,7 +288,7 @@ void CClient::Init()
LocalNetState.LastFrame = GetTicks();
LocalNetState.State = ccs_connecting;
LocalNetState.MsgCnt = 0;
LastStateMsgType = ICMServerQuit;
lastMsgTypeSent = ICMServerQuit;
}
void CClient::DetachFromServer()
@ -1073,7 +870,6 @@ void CClient::ParseBadMap()
NetConnectRunning = 0; // End the menu..
}
//
// CServer
//
@ -1263,7 +1059,6 @@ void CServer::ParseResync(const int h, unsigned long host, int port)
}
}
/**
** Parse client heart beat waiting message
**
@ -1590,31 +1385,10 @@ void CServer::NetworkParseMenuPacket(const CInitMessage &msg, unsigned long host
}
}
//
// Functions
//
/**
** Parse a Network menu packet.
**
** @param msg message received
** @param host host which send the message
** @param port port from where the message nas been sent
*/
static void NetworkParseMenuPacket(const CInitMessage &msg, unsigned long host, int port)
{
DebugPrint("Received %s Init Message %d:%d from %d.%d.%d.%d:%d (%ld)\n" _C_
icmsgsubtypenames[msg.SubType] _C_ msg.Type _C_ msg.SubType _C_ NIPQUAD(ntohl(host)) _C_
ntohs(port) _C_ FrameCounter);
if (NetConnectRunning == 2) { // client
Client.NetworkParseMenuPacket(msg, host, port);
} else if (NetConnectRunning == 1) { // server
Server.NetworkParseMenuPacket(msg, host, port);
}
}
/**
** Parse a setup event. (Command type <= MessageInitEvent)
**
@ -1652,7 +1426,15 @@ int NetworkParseSetupEvent(const unsigned char *buf, int size, unsigned long hos
return 0;
}
NetworkParseMenuPacket(msg, host, port);
DebugPrint("Received %s Init Message %d:%d from %d.%d.%d.%d:%d (%ld)\n" _C_
icmsgsubtypenames[msg.SubType] _C_ msg.Type _C_ msg.SubType _C_ NIPQUAD(ntohl(host)) _C_
ntohs(port) _C_ FrameCounter);
if (NetConnectRunning == 2) { // client
Client.NetworkParseMenuPacket(msg, host, port);
} else if (NetConnectRunning == 1) { // server
Server.NetworkParseMenuPacket(msg, host, port);
}
return 1;
}
@ -1664,7 +1446,6 @@ void NetworkProcessClientRequest()
Client.Update();
}
int GetNetworkState()
{
return Client.GetNetworkState();

View file

@ -222,8 +222,9 @@
#include "commands.h"
#include "interface.h"
#include "map.h"
#include "netconnect.h"
#include "net_lowlevel.h"
#include "net_message.h"
#include "netconnect.h"
#include "parameters.h"
#include "player.h"
#include "replay.h"
@ -234,7 +235,6 @@
#include "unittype.h"
#include "video.h"
//----------------------------------------------------------------------------
// Declaration
//----------------------------------------------------------------------------
@ -253,10 +253,24 @@ public:
CNetworkCommand Data; /// command content
};
/**
** Network Selection Info
*/
struct NetworkSelectionHeader
{
unsigned NumberSent : 6; /// New Number Selected
unsigned Add : 1; /// Adding to Selection
unsigned Remove : 1; /// Removing from Selection
unsigned char Type[MaxNetworkCommands]; /// Command
};
//----------------------------------------------------------------------------
// Variables
//----------------------------------------------------------------------------
char *NetworkAddr = NULL; /// Local network address to use
int NetworkPort = NetworkDefaultPort; /// Local network port to use
Socket NetworkFildes = static_cast<Socket>(-1); /// Network file descriptor
int NetworkInSync = 1; /// Network is in sync
int NetworkUpdates = 5; /// Network update each # game cycles
@ -291,142 +305,6 @@ static CNetworkCommandQueue NCQs[MAX_NCQS]; /// CNetworkCommandQueues
static int NumNCQs; /// Number of NCQs in use
//----------------------------------------------------------------------------
// Serialize/Deserialize
//----------------------------------------------------------------------------
void CNetworkCommand::Serialize(unsigned char *p) const
{
*(uint16_t *)p = this->Unit;
p += 2;
*(uint16_t *)p = this->X;
p += 2;
*(uint16_t *)p = this->Y;
p += 2;
*(uint16_t *)p = this->Dest;
p += 2;
}
void CNetworkCommand::Deserialize(const unsigned char *p)
{
this->Unit = *(uint16_t *)p;
p += 2;
this->X = *(uint16_t *)p;
p += 2;
this->Y = *(uint16_t *)p;
p += 2;
this->Dest = *(uint16_t *)p;
p += 2;
}
void CNetworkExtendedCommand::Serialize(unsigned char *p) const
{
*p++ = this->ExtendedType;
*p++ = this->Arg1;
*(uint16_t *)p = this->Arg2;
p += 2;
*(uint16_t *)p = this->Arg3;
p += 2;
*(uint16_t *)p = this->Arg4;
p += 2;
}
void CNetworkExtendedCommand::Deserialize(const unsigned char *p)
{
this->ExtendedType = *p++;
this->Arg1 = *p++;
this->Arg2 = *(uint16_t *)p;
p += 2;
this->Arg3 = *(uint16_t *)p;
p += 2;
this->Arg4 = *(uint16_t *)p;
p += 2;
}
void CNetworkChat::Serialize(unsigned char *p) const
{
*p++ = this->Player;
memcpy(p, this->Text, 7);
p += 7;
}
void CNetworkChat::Deserialize(const unsigned char *p)
{
this->Player = *p++;
memcpy(this->Text, p, 7);
p += 7;
}
void CNetworkPacketHeader::Serialize(unsigned char *p) const
{
*p++ = this->Cycle;
for (int i = 0; i < MaxNetworkCommands; ++i) {
*p++ = this->Type[i];
}
}
void CNetworkPacketHeader::Deserialize(const unsigned char *p)
{
this->Cycle = *p++;
for (int i = 0; i < MaxNetworkCommands; ++i) {
this->Type[i] = *p++;
}
}
unsigned char *CNetworkPacket::Serialize(int numcommands) const
{
unsigned char *buf = new unsigned char[CNetworkPacket::Size(numcommands)];
unsigned char *p = buf;
this->Header.Serialize(p);
p += CNetworkPacketHeader::Size();
for (int i = 0; i < numcommands; ++i) {
if (this->Header.Type[i] == MessageExtendedCommand) {
((CNetworkExtendedCommand *)&this->Command[i])->Serialize(p);
} else if (this->Header.Type[i] == MessageChat) {
((CNetworkChat *)&this->Command[i])->Serialize(p);
} else {
this->Command[i].Serialize(p);
}
p += CNetworkCommand::Size();
}
return buf;
}
int CNetworkPacket::Deserialize(const unsigned char *p, unsigned int len)
{
// check min and max size
if (len < CNetworkPacket::Size(1)
|| len > CNetworkPacket::Size(MaxNetworkCommands)) {
return -1;
}
// can't have partial commands
len -= CNetworkPacketHeader::Size();
if ((len / CNetworkCommand::Size()) * CNetworkCommand::Size() != len) {
return -1;
}
this->Header.Deserialize(p);
p += CNetworkPacketHeader::Size();
int commands = len / CNetworkCommand::Size();
for (int i = 0; i < commands; ++i) {
if (this->Header.Type[i] == MessageExtendedCommand) {
((CNetworkExtendedCommand *)&this->Command[i])->Deserialize(p);
} else if (this->Header.Type[i] == MessageChat) {
((CNetworkChat *)&this->Command[i])->Deserialize(p);
} else {
this->Command[i].Deserialize(p);
}
p += CNetworkCommand::Size();
}
return commands;
}
//----------------------------------------------------------------------------
// Mid-Level api functions
//----------------------------------------------------------------------------

View file

@ -30,6 +30,7 @@
#include <UnitTest++.h>
#include <TestReporterStdout.h>
#include <SDL.h>
int main(int argc, char* argv[])
{

View file

@ -31,7 +31,7 @@
#include "stratagus.h"
#include "network.h"
#include "net_message.h"
void FillCustomValue(CNetworkCommand *obj)
{