Move network messages into its own file.
This commit is contained in:
parent
0969b1cb27
commit
8c58c7b05e
10 changed files with 784 additions and 685 deletions
|
@ -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
340
src/include/net_message.h
Normal 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
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
398
src/network/net_message.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//@}
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <UnitTest++.h>
|
||||
#include <TestReporterStdout.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "stratagus.h"
|
||||
#include "network.h"
|
||||
|
||||
#include "net_message.h"
|
||||
|
||||
void FillCustomValue(CNetworkCommand *obj)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue