Changeset View
Changeset View
Standalone View
Standalone View
source/network/NetMessages.h
Show All 9 Lines | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
* GNU General Public License for more details. | * GNU General Public License for more details. | ||||
* | * | ||||
* You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | ||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
/** | |||||
* @file | |||||
* The list of messages used by the network subsystem. | |||||
*/ | |||||
#ifndef NETMESSAGES_H | #ifndef NETMESSAGES_H | ||||
#define NETMESSAGES_H | #define NETMESSAGES_H | ||||
#include "NetMessageBuffer.h" | |||||
#include "ps/CStr.h" | #include "ps/CStr.h" | ||||
#include "scriptinterface/ScriptVal.h" | |||||
#define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?' | #define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?' | ||||
#define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!' | #define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!' | ||||
#define PS_PROTOCOL_VERSION 0x01010015 // Arbitrary protocol | #define PS_PROTOCOL_VERSION 0x01010016 // Arbitrary protocol | ||||
#define PS_DEFAULT_PORT 0x5073 // 'P', 's' | #define PS_DEFAULT_PORT 0x5073 // 'P', 's' | ||||
// Defines the list of message types. The order of the list must not change. | |||||
// The message types having a negative value are used internally and not sent | |||||
// over the network. The message types used for network communication have | |||||
// positive values. | |||||
enum NetMessageType | |||||
{ | |||||
NMT_CONNECT_COMPLETE = -256, | |||||
NMT_CONNECTION_LOST, | |||||
NMT_INVALID = 0, | |||||
NMT_SERVER_HANDSHAKE, | |||||
NMT_CLIENT_HANDSHAKE, | |||||
NMT_SERVER_HANDSHAKE_RESPONSE, | |||||
NMT_AUTHENTICATE, | |||||
NMT_AUTHENTICATE_RESULT, | |||||
NMT_CHAT, | |||||
NMT_READY, | |||||
NMT_CLEAR_ALL_READY, | |||||
NMT_GAME_SETUP, | |||||
NMT_ASSIGN_PLAYER, | |||||
NMT_PLAYER_ASSIGNMENT, | |||||
NMT_FILE_TRANSFER_REQUEST, | |||||
NMT_FILE_TRANSFER_RESPONSE, | |||||
NMT_FILE_TRANSFER_DATA, | |||||
NMT_FILE_TRANSFER_ACK, | |||||
NMT_JOIN_SYNC_START, | |||||
NMT_REJOINED, | |||||
NMT_KICKED, | |||||
NMT_CLIENT_TIMEOUT, | |||||
NMT_CLIENT_PERFORMANCE, | |||||
NMT_CLIENTS_LOADING, | |||||
NMT_CLIENT_PAUSED, | |||||
NMT_LOADED_GAME, | |||||
NMT_GAME_START, | |||||
NMT_END_COMMAND_BATCH, | |||||
NMT_SYNC_CHECK, // OOS-detection hash checking | |||||
NMT_SYNC_ERROR, // OOS-detection error | |||||
NMT_SIMULATION_COMMAND | |||||
}; | |||||
// Authentication result codes | // Authentication result codes | ||||
enum AuthenticateResultCode | enum AuthenticateResultCode | ||||
{ | { | ||||
ARC_OK, | ARC_OK, | ||||
ARC_OK_REJOINING, | ARC_OK_REJOINING, | ||||
ARC_PASSWORD_INVALID, | ARC_PASSWORD_INVALID, | ||||
}; | }; | ||||
#endif // NETMESSAGES_H | /** | ||||
* Special message type for simulation commands. | |||||
* These commands are exposed as arbitrary JS objects, associated with a specific player. | |||||
*/ | |||||
class CSimulationMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_SIMULATION_COMMAND; | |||||
CSimulationMessage(ScriptInterface& scriptInterface) : | |||||
m_JSData(SerializableJSValue{scriptInterface, {}}) | |||||
{ | |||||
} | |||||
CSimulationMessage(ScriptInterface& scriptInterface, u32 client, i32 player, u32 turn, JS::HandleValue data) : | |||||
m_Client(client), | |||||
m_Player(player), | |||||
m_Turn(turn), | |||||
m_JSData(SerializableJSValue{scriptInterface, {scriptInterface.GetJSRuntime(), data}}) | |||||
{ | |||||
} | |||||
CSimulationMessage(const CSimulationMessage& orig) : | |||||
m_Client(orig.m_Client), | |||||
m_Player(orig.m_Player), | |||||
m_Turn(orig.m_Turn), | |||||
m_JSData(orig.m_JSData) | |||||
{ | |||||
} | |||||
u32 m_Client; | |||||
i32 m_Player; | |||||
u32 m_Turn; | |||||
SerializableJSValue m_JSData; | |||||
REGISTER_SERIALIZABLE(m_Client, m_Player, m_Turn, m_JSData) | |||||
}; | |||||
/** | |||||
* Special message type for updates to game settings. | |||||
*/ | |||||
class CGameSetupMessage : ISerializable | |||||
{ | |||||
NONCOPYABLE(CGameSetupMessage); | |||||
public: | |||||
static const NetMessageType type = NMT_GAME_SETUP; | |||||
CGameSetupMessage(ScriptInterface& scriptInterface) : | |||||
m_JSData(SerializableJSValue{scriptInterface, {}}) | |||||
{ | |||||
} | |||||
CGameSetupMessage(ScriptInterface& scriptInterface, JS::HandleValue data) : | |||||
m_JSData(SerializableJSValue{scriptInterface, {scriptInterface.GetJSRuntime(), data}}) | |||||
{ | |||||
} | |||||
SerializableJSValue m_JSData; | |||||
REGISTER_SERIALIZABLE(m_JSData) | |||||
}; | |||||
class CSrvHandshakeMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_SERVER_HANDSHAKE; | |||||
u32 m_Magic; | |||||
u32 m_ProtocolVersion; | |||||
u32 m_SoftwareVersion; | |||||
REGISTER_SERIALIZABLE(m_Magic, m_ProtocolVersion, m_SoftwareVersion) | |||||
}; | |||||
class CCliHandshakeMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_CLIENT_HANDSHAKE; | |||||
u32 m_MagicResponse; | |||||
u32 m_ProtocolVersion; | |||||
u32 m_SoftwareVersion; | |||||
REGISTER_SERIALIZABLE(m_MagicResponse, m_ProtocolVersion, m_SoftwareVersion) | |||||
}; | |||||
class CSrvHandshakeResponseMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_SERVER_HANDSHAKE_RESPONSE; | |||||
u32 m_UseProtocolVersion; | |||||
u32 m_Flags; | |||||
CStrW m_Message; | |||||
REGISTER_SERIALIZABLE(m_UseProtocolVersion, m_Flags, m_Message) | |||||
}; | |||||
class CAuthenticateMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_AUTHENTICATE; | |||||
CStr m_GUID; | |||||
CStrW m_Name; | |||||
CStrW m_Password; | |||||
u8 m_IsLocalClient; | |||||
REGISTER_SERIALIZABLE(m_GUID, m_Name, m_Password, m_IsLocalClient) | |||||
}; | |||||
class CAuthenticateResultMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_AUTHENTICATE_RESULT; | |||||
u32 m_Code; | |||||
u16 m_HostID; | |||||
CStrW m_Message; | |||||
REGISTER_SERIALIZABLE(m_Code, m_HostID, m_Message) | |||||
}; | |||||
class CChatMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_CHAT; | |||||
CStr m_GUID; // ignored when client->server, valid when server->client | |||||
CStrW m_Message; | |||||
REGISTER_SERIALIZABLE(m_GUID, m_Message) | |||||
}; | |||||
class CReadyMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_READY; | |||||
#ifdef CREATING_NMT | CStr m_GUID; // ignored when client->server, valid when server->client | ||||
u8 m_Status; | |||||
#define ALLNETMSGS_DONT_CREATE_NMTS | REGISTER_SERIALIZABLE(m_GUID, m_Status) | ||||
#define START_NMT_CLASS_(_nm, _message) START_NMT_CLASS(C##_nm##Message, _message) | }; | ||||
#define DERIVE_NMT_CLASS_(_base, _nm, _message) START_NMT_CLASS_DERIVED(C ## _base ## Message, C ## _nm ## Message, _message) | |||||
class CClearAllReadyMessage : ISerializable | |||||
START_NMTS() | { | ||||
public: | |||||
START_NMT_CLASS_(SrvHandshake, NMT_SERVER_HANDSHAKE) | static const NetMessageType type = NMT_CLEAR_ALL_READY; | ||||
NMT_FIELD_INT(m_Magic, u32, 4) | |||||
NMT_FIELD_INT(m_ProtocolVersion, u32, 4) | REGISTER_SERIALIZABLE_EMPTY() | ||||
NMT_FIELD_INT(m_SoftwareVersion, u32, 4) | }; | ||||
END_NMT_CLASS() | |||||
class CPlayerAssignmentMessage : ISerializable | |||||
START_NMT_CLASS_(CliHandshake, NMT_CLIENT_HANDSHAKE) | { | ||||
NMT_FIELD_INT(m_MagicResponse, u32, 4) | public: | ||||
NMT_FIELD_INT(m_ProtocolVersion, u32, 4) | static const NetMessageType type = NMT_PLAYER_ASSIGNMENT; | ||||
NMT_FIELD_INT(m_SoftwareVersion, u32, 4) | |||||
END_NMT_CLASS() | struct SHost : ISerializable | ||||
{ | |||||
START_NMT_CLASS_(SrvHandshakeResponse, NMT_SERVER_HANDSHAKE_RESPONSE) | CStr m_GUID; | ||||
NMT_FIELD_INT(m_UseProtocolVersion, u32, 4) | CStrW m_Name; | ||||
NMT_FIELD_INT(m_Flags, u32, 4) | i8 m_PlayerID; | ||||
NMT_FIELD(CStrW, m_Message) | u8 m_Status; | ||||
END_NMT_CLASS() | |||||
REGISTER_SERIALIZABLE(m_GUID, m_Name, m_PlayerID, m_Status) | |||||
START_NMT_CLASS_(Authenticate, NMT_AUTHENTICATE) | }; | ||||
NMT_FIELD(CStr, m_GUID) | |||||
NMT_FIELD(CStrW, m_Name) | std::vector<SHost> m_Hosts; | ||||
NMT_FIELD(CStrW, m_Password) | |||||
NMT_FIELD_INT(m_IsLocalClient, u8, 1) | REGISTER_SERIALIZABLE(m_Hosts) | ||||
END_NMT_CLASS() | }; | ||||
START_NMT_CLASS_(AuthenticateResult, NMT_AUTHENTICATE_RESULT) | class CFileTransferRequestMessage : ISerializable | ||||
NMT_FIELD_INT(m_Code, u32, 4) | { | ||||
NMT_FIELD_INT(m_HostID, u32, 2) | public: | ||||
NMT_FIELD(CStrW, m_Message) | static const NetMessageType type = NMT_FILE_TRANSFER_REQUEST; | ||||
END_NMT_CLASS() | |||||
u32 m_RequestID; | |||||
START_NMT_CLASS_(Chat, NMT_CHAT) | |||||
NMT_FIELD(CStr, m_GUID) // ignored when client->server, valid when server->client | REGISTER_SERIALIZABLE(m_RequestID) | ||||
NMT_FIELD(CStrW, m_Message) | }; | ||||
END_NMT_CLASS() | |||||
class CFileTransferResponseMessage : ISerializable | |||||
START_NMT_CLASS_(Ready, NMT_READY) | { | ||||
NMT_FIELD(CStr, m_GUID) | public: | ||||
NMT_FIELD_INT(m_Status, u8, 1) | static const NetMessageType type = NMT_FILE_TRANSFER_RESPONSE; | ||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(ClearAllReady, NMT_CLEAR_ALL_READY) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(PlayerAssignment, NMT_PLAYER_ASSIGNMENT) | |||||
NMT_START_ARRAY(m_Hosts) | |||||
NMT_FIELD(CStr, m_GUID) | |||||
NMT_FIELD(CStrW, m_Name) | |||||
NMT_FIELD_INT(m_PlayerID, i8, 1) | |||||
NMT_FIELD_INT(m_Status, u8, 1) | |||||
NMT_END_ARRAY() | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(FileTransferRequest, NMT_FILE_TRANSFER_REQUEST) | |||||
NMT_FIELD_INT(m_RequestID, u32, 4) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(FileTransferResponse, NMT_FILE_TRANSFER_RESPONSE) | |||||
NMT_FIELD_INT(m_RequestID, u32, 4) | |||||
NMT_FIELD_INT(m_Length, u32, 4) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(FileTransferData, NMT_FILE_TRANSFER_DATA) | |||||
NMT_FIELD_INT(m_RequestID, u32, 4) | |||||
NMT_FIELD(CStr, m_Data) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(FileTransferAck, NMT_FILE_TRANSFER_ACK) | |||||
NMT_FIELD_INT(m_RequestID, u32, 4) | |||||
NMT_FIELD_INT(m_NumPackets, u32, 4) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(JoinSyncStart, NMT_JOIN_SYNC_START) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(Rejoined, NMT_REJOINED) | |||||
NMT_FIELD(CStr, m_GUID) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(Kicked, NMT_KICKED) | |||||
NMT_FIELD(CStrW, m_Name) | |||||
NMT_FIELD_INT(m_Ban, u8, 1) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(ClientTimeout, NMT_CLIENT_TIMEOUT) | |||||
NMT_FIELD(CStr, m_GUID) | |||||
NMT_FIELD_INT(m_LastReceivedTime, u32, 4) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(ClientPerformance, NMT_CLIENT_PERFORMANCE) | |||||
NMT_START_ARRAY(m_Clients) | |||||
NMT_FIELD(CStr, m_GUID) | |||||
NMT_FIELD_INT(m_MeanRTT, u32, 4) | |||||
NMT_END_ARRAY() | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(ClientsLoading, NMT_CLIENTS_LOADING) | |||||
NMT_START_ARRAY(m_Clients) | |||||
NMT_FIELD(CStr, m_GUID) | |||||
NMT_END_ARRAY() | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(ClientPaused, NMT_CLIENT_PAUSED) | |||||
NMT_FIELD(CStr, m_GUID) | |||||
NMT_FIELD_INT(m_Pause, u8, 1) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(LoadedGame, NMT_LOADED_GAME) | |||||
NMT_FIELD_INT(m_CurrentTurn, u32, 4) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(GameStart, NMT_GAME_START) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(EndCommandBatch, NMT_END_COMMAND_BATCH) | |||||
NMT_FIELD_INT(m_Turn, u32, 4) | |||||
NMT_FIELD_INT(m_TurnLength, u32, 2) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(SyncCheck, NMT_SYNC_CHECK) | |||||
NMT_FIELD_INT(m_Turn, u32, 4) | |||||
NMT_FIELD(CStr, m_Hash) | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(SyncError, NMT_SYNC_ERROR) | |||||
NMT_FIELD_INT(m_Turn, u32, 4) | |||||
NMT_FIELD(CStr, m_HashExpected) | |||||
NMT_START_ARRAY(m_PlayerNames) | |||||
NMT_FIELD(CStrW, m_Name) | |||||
NMT_END_ARRAY() | |||||
END_NMT_CLASS() | |||||
START_NMT_CLASS_(AssignPlayer, NMT_ASSIGN_PLAYER) | |||||
NMT_FIELD_INT(m_PlayerID, i8, 1) | |||||
NMT_FIELD(CStr, m_GUID) | |||||
END_NMT_CLASS() | |||||
END_NMTS() | |||||
#else | |||||
#ifndef ALLNETMSGS_DONT_CREATE_NMTS | |||||
# ifdef ALLNETMSGS_IMPLEMENT | |||||
# define NMT_CREATOR_IMPLEMENT | |||||
# endif | |||||
# define NMT_CREATE_HEADER_NAME "NetMessages.h" | u32 m_RequestID; | ||||
# include "NMTCreator.h" | u32 m_Length; | ||||
#endif // #ifndef ALLNETMSGS_DONT_CREATE_NMTS | REGISTER_SERIALIZABLE(m_RequestID, m_Length) | ||||
#endif // #ifdef CREATING_NMT | }; | ||||
class CFileTransferDataMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_FILE_TRANSFER_DATA; | |||||
u32 m_RequestID; | |||||
CStr m_Data; | |||||
REGISTER_SERIALIZABLE(m_RequestID, m_Data) | |||||
}; | |||||
class CFileTransferAckMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_FILE_TRANSFER_ACK; | |||||
u32 m_RequestID; | |||||
u32 m_NumPackets; | |||||
REGISTER_SERIALIZABLE(m_RequestID, m_NumPackets) | |||||
}; | |||||
class CJoinSyncStartMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_JOIN_SYNC_START; | |||||
REGISTER_SERIALIZABLE_EMPTY() | |||||
}; | |||||
class CRejoinedMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_REJOINED; | |||||
CStr m_GUID; | |||||
REGISTER_SERIALIZABLE(m_GUID) | |||||
}; | |||||
class CKickedMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_KICKED; | |||||
CStrW m_Name; | |||||
u8 m_Ban; | |||||
REGISTER_SERIALIZABLE(m_Name, m_Ban) | |||||
}; | |||||
class CClientTimeoutMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_CLIENT_TIMEOUT; | |||||
CStr m_GUID; | |||||
u32 m_LastReceivedTime; | |||||
REGISTER_SERIALIZABLE(m_GUID, m_LastReceivedTime) | |||||
}; | |||||
class CClientPerformanceMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_CLIENT_PERFORMANCE; | |||||
struct SClient : ISerializable | |||||
{ | |||||
CStr m_GUID; | |||||
u32 m_MeanRTT; | |||||
REGISTER_SERIALIZABLE(m_GUID, m_MeanRTT) | |||||
}; | |||||
std::vector<SClient> m_Clients; | |||||
REGISTER_SERIALIZABLE(m_Clients) | |||||
}; | |||||
class CClientsLoadingMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_CLIENTS_LOADING; | |||||
struct SClient : ISerializable | |||||
{ | |||||
CStr m_GUID; | |||||
REGISTER_SERIALIZABLE(m_GUID) | |||||
}; | |||||
std::vector<SClient> m_Clients; | |||||
REGISTER_SERIALIZABLE(m_Clients) | |||||
}; | |||||
class CClientPausedMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_CLIENT_PAUSED; | |||||
CStr m_GUID; | |||||
u8 m_Pause; | |||||
REGISTER_SERIALIZABLE(m_GUID, m_Pause) | |||||
}; | |||||
class CLoadedGameMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_LOADED_GAME; | |||||
u32 m_CurrentTurn; | |||||
REGISTER_SERIALIZABLE(m_CurrentTurn) | |||||
}; | |||||
class CGameStartMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_GAME_START; | |||||
REGISTER_SERIALIZABLE_EMPTY() | |||||
}; | |||||
class CEndCommandBatchMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_END_COMMAND_BATCH; | |||||
u32 m_Turn; | |||||
u16 m_TurnLength; | |||||
REGISTER_SERIALIZABLE(m_Turn, m_TurnLength) | |||||
}; | |||||
class CSyncCheckMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_SYNC_CHECK; | |||||
u32 m_Turn; | |||||
CStr m_Hash; | |||||
REGISTER_SERIALIZABLE(m_Turn, m_Hash) | |||||
}; | |||||
class CSyncErrorMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_SYNC_ERROR; | |||||
u32 m_Turn; | |||||
CStr m_HashExpected; | |||||
std::vector<CStrW> m_PlayerNames; | |||||
REGISTER_SERIALIZABLE(m_Turn, m_HashExpected, m_PlayerNames) | |||||
}; | |||||
class CAssignPlayerMessage : ISerializable | |||||
{ | |||||
public: | |||||
static const NetMessageType type = NMT_ASSIGN_PLAYER; | |||||
i8 m_PlayerID; | |||||
CStr m_GUID; | |||||
REGISTER_SERIALIZABLE(m_PlayerID, m_GUID) | |||||
}; | |||||
#endif // NETMESSAGES_H | |||||
leper: Possibly `const&`, if D739 gets merged first. |
Wildfire Games · Phabricator
Possibly const&, if D739 gets merged first.