1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #ifndef _BASE_NET_PROTOCOL_H
4 #define _BASE_NET_PROTOCOL_H
5 
6 #include <boost/shared_ptr.hpp>
7 #include <boost/cstdint.hpp>
8 #include <vector>
9 #include <string>
10 #include <stdlib.h>
11 #include "Game/GameVersion.h"
12 
13 
14 namespace netcode
15 {
16 	class RawPacket;
17 }
18 struct PlayerStatistics;
19 
20 
21 static const unsigned short NETWORK_VERSION = atoi(SpringVersion::GetMajor().c_str());
22 
23 
24 /*
25  * Comment behind NETMSG enumeration constant gives the extra data belonging to
26  * the net message.
27  * An empty comment means no extra data (message is only 1 byte).
28  * Messages either consist of:
29  *  1. uchar command; (NETMSG_* constant) and the specified extra data; or
30  *  2. uchar command; uchar messageSize; and the specified extra data,
31  *     for messages that contain a trailing std::string in the extra data; or
32  *  3. uchar command; short messageSize; and the specified extra data,
33  *     for messages that contain a trailing std::vector in the extra data.
34  * Note that NETMSG_MAPDRAW can behave like 1. or 2. depending on the
35  * MapDrawAction::NET_* command. messageSize is always the size of the entire
36  * message in bytes, including 'command' and 'messageSize'.
37  */
38 
39 enum NETMSG {
40 	NETMSG_KEYFRAME         = 1,  // int framenum
41 	NETMSG_NEWFRAME         = 2,  //
42 	NETMSG_QUIT             = 3,  // string reason
43 	NETMSG_STARTPLAYING     = 4,  // uint countdown
44 	NETMSG_SETPLAYERNUM     = 5,  // uchar myPlayerNum;
45 	NETMSG_PLAYERNAME       = 6,  // uchar myPlayerNum; std::string playerName;
46 	NETMSG_CHAT             = 7,  // uchar from, dest; std::string message;
47 	NETMSG_RANDSEED         = 8,  // uint randSeed;
48 	NETMSG_GAMEID           = 9,  // uchar gameID[16];
49 	NETMSG_PATH_CHECKSUM    = 10, // uchar myPlayerNum, boost::uint32_t checksum
50 	NETMSG_COMMAND          = 11, // uchar myPlayerNum; int id; uchar options; std::vector<float> params;
51 	NETMSG_SELECT           = 12, // uchar myPlayerNum; std::vector<short> selectedUnitIDs;
52 	NETMSG_PAUSE            = 13, // uchar playerNum, bPaused;
53 
54 	NETMSG_AICOMMAND        = 14, // uchar myPlayerNum; uchar aiID; short unitID; int id; uchar options; std::vector<float> params;
55 	NETMSG_AICOMMANDS       = 15, // uchar myPlayerNum; uchar aiID; uchar pairwise, uint sameCmdID, uchar sameCmdOpt, ushort sameCmdParamSize;
56 	                              // short unitIDCount;  unitIDCount * short(unitID)
57 	                              // short commandCount; commandCount * { int id; uchar options; std::vector<float> params }
58 	NETMSG_AISHARE          = 16, // uchar myPlayerNum, uchar aiID, uchar sourceTeam, uchar destTeam, float metal, float energy, std::vector<short> unitIDs
59 
60 	NETMSG_USER_SPEED       = 19, // uchar myPlayerNum, float userSpeed;
61 	NETMSG_INTERNAL_SPEED   = 20, // float internalSpeed;
62 	NETMSG_CPU_USAGE        = 21, // float cpuUsage;
63 	NETMSG_DIRECT_CONTROL   = 22, // uchar myPlayerNum;
64 	NETMSG_DC_UPDATE        = 23, // uchar myPlayerNum, status; short heading, pitch;
65 	NETMSG_SHARE            = 26, // uchar myPlayerNum, shareTeam, bShareUnits; float shareMetal, shareEnergy;
66 	NETMSG_SETSHARE         = 27, // uchar myPlayerNum, uchar myTeam; float metalShareFraction, energyShareFraction;
67 
68 	NETMSG_PLAYERSTAT       = 29, // uchar myPlayerNum; CPlayer::Statistics currentStats;
69 	NETMSG_GAMEOVER         = 30, // uchar myPlayerNum; std::vector<uchar> winningAllyTeams
70 	NETMSG_MAPDRAW          = 31, // uchar messageSize =  8, myPlayerNum, command = MapDrawAction::NET_ERASE; short x, z;
71 	                              // uchar messageSize = 12, myPlayerNum, command = MapDrawAction::NET_LINE; short x1, z1, x2, z2;
72 	                              // /*messageSize*/   uchar myPlayerNum, command = MapDrawAction::NET_POINT; short x, z; std::string label;
73 	NETMSG_SYNCRESPONSE     = 33, // uchar myPlayerNum; int frameNum; uint checksum;
74 	NETMSG_SYSTEMMSG        = 35, // uchar myPlayerNum, std::string message;
75 	NETMSG_STARTPOS         = 36, // uchar myPlayerNum, uchar myTeam, ready /*0: not ready, 1: ready, 2: don't update readiness*/; float x, y, z;
76 	NETMSG_PLAYERINFO       = 38, // uchar myPlayerNum; float cpuUsage; int ping /*in frames*/;
77 	NETMSG_PLAYERLEFT       = 39, // uchar myPlayerNum, bIntended /*0: lost connection, 1: left, 2: forced (kicked) */;
78 
79 #ifdef SYNCDEBUG
80 	NETMSG_SD_CHKREQUEST    = 41,
81 	NETMSG_SD_CHKRESPONSE   = 42,
82 	NETMSG_SD_BLKREQUEST    = 43,
83 	NETMSG_SD_BLKRESPONSE   = 44,
84 	NETMSG_SD_RESET         = 45,
85 #endif // SYNCDEBUG
86 
87 	NETMSG_LUAMSG           = 50, // /* uint16_t messageSize */, uchar myPlayerNum, unsigned short script, uchar mode, std::vector<uint8_t> msg
88 	NETMSG_TEAM             = 51, // uchar myPlayerNum, uchar action, uchar parameter1
89 	NETMSG_GAMEDATA         = 52, // /* uchar messageSize */, std::string setupText, std::string script, std::string map, int mapChecksum,
90 	                              // std::string mod, int modChecksum, int randomSeed (each string ends with \0)
91 	NETMSG_ALLIANCE         = 53, // uchar myPlayerNum, uchar otherAllyTeam, uchar allianceState (0 = not allied / 1 = allied)
92 	NETMSG_CCOMMAND         = 54, // /* short! messageSize */, int! myPlayerNum, std::string command, std::string extra (each string ends with \0)
93 	NETMSG_TEAMSTAT         = 60, // uchar teamNum, struct TeamStatistics statistics      # used by LadderBot #
94 
95 	NETMSG_ATTEMPTCONNECT   = 65, // ushort msgsize, ushort netversion, string playername, string passwd, string VERSION_STRING_DETAILED
96 
97 	NETMSG_AI_CREATED       = 70, // /* uchar messageSize */, uchar myPlayerNum, uchar whichSkirmishAI, uchar team, std::string name (ends with \0)
98 	NETMSG_AI_STATE_CHANGED = 71, // uchar myPlayerNum, uchar whichSkirmishAI, uchar newState
99 
100 	NETMSG_REQUEST_TEAMSTAT = 72, // uchar teamNum, ushort statFrameNum                   # used by LadderBot #
101 
102 	NETMSG_CREATE_NEWPLAYER = 75, // uchar myPlayerNum, uchar spectator, uchar teamNum, std::string playerName #used for players not preset in script.txt#
103 
104 	NETMSG_AICOMMAND_TRACKED= 76,  // uchar myPlayerNum; uchar aiID; short unitID; int id; uchar options; int aiCommandId, std::vector<float> params;
105 
106 	NETMSG_GAME_FRAME_PROGRESS= 77, // int frameNum # this special packet skips queue & cache entirely, indicates current game progress for clients fast-forwarding to current point the game #
107 
108 
109 	NETMSG_LAST //max types of netmessages, internal only
110 };
111 
112 
113 /// sub-action-types of NETMSG_TEAM
114 enum TEAMMSG {
115 //	TEAMMSG_NAME            = number    parameter1, ...
116 	TEAMMSG_GIVEAWAY        = 1,     // team to give stuff to, team to take stuff from (player has to be leader of the team)
117 	TEAMMSG_RESIGN          = 2,     // not used
118 	TEAMMSG_JOIN_TEAM       = 3,     // team to join
119 	TEAMMSG_TEAM_DIED       = 4,     // team which had died special note: this is sent by all players to prevent cheating
120 //TODO: changing teams (to spectator, from spectator to specific team)
121 //TODO: in-game allyteams
122 };
123 
124 /// sub-action-types of NETMSG_MAPDRAW
125 enum MapDrawAction {
126 	MAPDRAW_POINT,
127 	MAPDRAW_ERASE,
128 	MAPDRAW_LINE
129 };
130 
131 /**
132  * @brief A factory used to make often-used network messages.
133  *
134  * Use this if you want to create a network message. Implemented as a singleton.
135  */
136 class CBaseNetProtocol
137 {
138 public:
139 	typedef unsigned char uchar;
140 	typedef unsigned int uint;
141 	typedef boost::shared_ptr<const netcode::RawPacket> PacketType;
142 
143 	static CBaseNetProtocol& Get();
144 
145 	PacketType SendKeyFrame(int frameNum);
146 	PacketType SendNewFrame();
147 	PacketType SendQuit(const std::string& reason);
148 	/// client can send these to force-start the game
149 	PacketType SendStartPlaying(unsigned countdown);
150 	PacketType SendSetPlayerNum(uchar myPlayerNum);
151 	PacketType SendPlayerName(uchar myPlayerNum, const std::string& playerName);
152 	PacketType SendRandSeed(uint randSeed);
153 	PacketType SendGameID(const uchar* buf);
154 	PacketType SendPathCheckSum(uchar myPlayerNum, boost::uint32_t checksum);
155 	PacketType SendCommand(uchar myPlayerNum, int id, uchar options, const std::vector<float>& params);
156 	PacketType SendSelect(uchar myPlayerNum, const std::vector<short>& selectedUnitIDs);
157 	PacketType SendPause(uchar myPlayerNum, uchar bPaused);
158 
159 	PacketType SendAICommand(uchar myPlayerNum, unsigned char aiID, short unitID, int id, int aiCommandId, uchar options, const std::vector<float>& params);
160 	PacketType SendAIShare(uchar myPlayerNum, unsigned char aiID, uchar sourceTeam, uchar destTeam, float metal, float energy, const std::vector<short>& unitIDs);
161 
162 	PacketType SendUserSpeed(uchar myPlayerNum, float userSpeed);
163 	PacketType SendInternalSpeed(float internalSpeed);
164 	PacketType SendCPUUsage(float cpuUsage);
165 	PacketType SendCustomData(uchar myPlayerNum, uchar dataType, int dataValue);
166 	PacketType SendLuaDrawTime(uchar myPlayerNum, int mSec);
167 	PacketType SendDirectControl(uchar myPlayerNum);
168 	PacketType SendDirectControlUpdate(uchar myPlayerNum, uchar status, short heading, short pitch);
169 	PacketType SendAttemptConnect(const std::string& name, const std::string& passwd, const std::string& version, int netloss, bool reconnect = false);
170 	PacketType SendShare(uchar myPlayerNum, uchar shareTeam, uchar bShareUnits, float shareMetal, float shareEnergy);
171 	PacketType SendSetShare(uchar myPlayerNum, uchar myTeam, float metalShareFraction, float energyShareFraction);
172 	PacketType SendPlayerStat(uchar myPlayerNum, const PlayerStatistics& currentStats);
173 	PacketType SendGameOver(uchar myPlayerNum, const std::vector<uchar>& winningAllyTeams);
174 	PacketType SendMapErase(uchar myPlayerNum, short x, short z);
175 	PacketType SendMapDrawLine(uchar myPlayerNum, short x1, short z1, short x2, short z2, bool);
176 	PacketType SendMapDrawPoint(uchar myPlayerNum, short x, short z, const std::string& label, bool);
177 	PacketType SendSyncResponse(uchar myPlayerNum, int frameNum, uint checksum);
178 	PacketType SendSystemMessage(uchar myPlayerNum, std::string message);
179 	PacketType SendStartPos(uchar myPlayerNum, uchar teamNum, uchar readyState, float x, float y, float z);
180 	PacketType SendPlayerInfo(uchar myPlayerNum, float cpuUsage, int ping);
181 	PacketType SendPlayerLeft(uchar myPlayerNum, uchar bIntended);
182 	PacketType SendLuaMsg(uchar myPlayerNum, unsigned short script, uchar mode, const std::vector<boost::uint8_t>& msg);
183 	PacketType SendCurrentFrameProgress(int frameNum);
184 
185 	PacketType SendGiveAwayEverything(uchar myPlayerNum, uchar giveToTeam);
186 	/**
187 	 * Gives everything from one team to another.
188 	 * The player issuing this command has to be leader of the takeFromTeam.
189 	 */
190 	PacketType SendGiveAwayEverything(uchar myPlayerNum, uchar giveToTeam, uchar takeFromTeam);
191 	PacketType SendResign(uchar myPlayerNum);
192 	PacketType SendJoinTeam(uchar myPlayerNum, uchar wantedTeamNum);
193 	/**
194 	 * This is currently only used to inform the server about its death.
195 	 * It may have some problems when desync, because the team may not die
196 	 * on every client.
197 	 */
198 	PacketType SendTeamDied(uchar myPlayerNum, uchar whichTeam);
199 
200 	PacketType SendAICreated(const uchar myPlayerNum,
201 	                         const uchar whichSkirmishAI,
202 	                         const uchar team,
203 	                         const std::string& name);
204 	PacketType SendAIStateChanged(const uchar myPlayerNum,
205 	                              const uchar whichSkirmishAI,
206 	                              const uchar newState);
207 
208 	PacketType SendSetAllied(uchar myPlayerNum, uchar whichAllyTeam, uchar state);
209 
210 	PacketType SendCreateNewPlayer( uchar playerNum, bool spectator, uchar teamNum, std::string playerName);
211 
212 #ifdef SYNCDEBUG
213 	PacketType SendSdCheckrequest(int frameNum);
214 	PacketType SendSdCheckresponse(uchar myPlayerNum, boost::uint64_t flop, std::vector<unsigned> checksums);
215 	PacketType SendSdReset();
216 	PacketType SendSdBlockrequest(unsigned short begin, unsigned short length, unsigned short requestSize);
217 	PacketType SendSdBlockresponse(uchar myPlayerNum, std::vector<unsigned> checksums);
218 #endif
219 private:
220 	CBaseNetProtocol();
221 	~CBaseNetProtocol();
222 };
223 
224 #endif // _BASE_NET_PROTOCOL_H
225