File: AutohostInterface.cpp

package info (click to toggle)
spring 0.81.2.1%2Bdfsg1-6
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 28,496 kB
  • ctags: 37,096
  • sloc: cpp: 238,659; ansic: 13,784; java: 12,175; awk: 3,428; python: 1,159; xml: 738; perl: 405; sh: 297; makefile: 267; pascal: 228; objc: 192
file content (215 lines) | stat: -rw-r--r-- 5,763 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#ifdef _MSC_VER
#	include "StdAfx.h"
#elif defined(_WIN32)
#	include <windows.h>
#endif

#include "Net/Socket.h" 

#ifndef _MSC_VER
#	include "StdAfx.h"
#endif

#include "AutohostInterface.h"

#include <string.h>
#include <vector>
#include "mmgr.h"
#include "LogOutput.h"

namespace {

/**
@enum EVENT Which events can be sent to the autohost (in bracets: parameters, where uchar means unsigned char and "string" means plain ascii text)
*/
enum EVENT
{
	/// Server has started ()
	SERVER_STARTED = 0,
 
	/// Server is about to exit ()
	SERVER_QUIT = 1,

	/// Game starts ()
	SERVER_STARTPLAYING = 2,
 
	/// Game has ended ()
	SERVER_GAMEOVER = 3,
	
	/// An information message from server (string message)
	SERVER_MESSAGE = 4,
	
	/// Server gave out a warning (string warningmessage)
	SERVER_WARNING = 5,
	
	/// Player has joined the game (uchar playernumber, string name)
	PLAYER_JOINED = 10,
 
	/// Player has left (uchar playernumber, uchar reason (0: lost connection, 1: left, 2: kicked) )
	PLAYER_LEFT = 11,
 
	/// Player has updated its ready-state (uchar playernumber, uchar state (0: not ready, 1: ready, 2: state not changed) )
	PLAYER_READY = 12,

	/**
	@brief Player has sent a chat message (uchar playernumber, uchar destination, string text)
	Destination can be any of: a playernumber [0-32]
	static const int TO_ALLIES = 127;
	static const int TO_SPECTATORS = 126;
	static const int TO_EVERYONE = 125;
	(copied from Game/ChatMessage.h)
	*/
	PLAYER_CHAT = 13,
 
	/// Player has been defeated (uchar playernumber)
	PLAYER_DEFEATED = 14,

	/**
	 * @brief Message sent by lua script
	 * 
	 * (uchar playernumber, uint16_t script, uint8_t mode, uint8_t[X] data) (X = space left in packet)
	 * */
	GAME_LUAMSG = 20,
	
	/// team statistics, see CTeam::Statistics for reference how to read them
	/**
	* (uchar teamnumber), CTeam::Statistics(in binary form)
	*/
	GAME_TEAMSTAT = 60
};
}

using namespace boost::asio;
AutohostInterface::AutohostInterface(const std::string& autohostip, int remoteport) : autohost(netcode::netservice)
{
	boost::system::error_code err;
	autohost.open(ip::udp::v6(), err); // test v6
	if (!err)
	{
		autohost.bind(ip::udp::endpoint(ip::address_v6::any(), 0));
	}
	else
	{
		LogObject() << "IPv6 not supported, falling back to v4";
		autohost.open(ip::udp::v4());
		autohost.bind(ip::udp::endpoint(ip::address_v4::any(), 0));
	}
	boost::asio::socket_base::non_blocking_io command(true);
	autohost.io_control(command);

	autohost.connect(netcode::ResolveAddr(autohostip, remoteport));
}

AutohostInterface::~AutohostInterface()
{
}

void AutohostInterface::SendStart()
{
	uchar msg = SERVER_STARTED;
	autohost.send(boost::asio::buffer(&msg, sizeof(uchar)));
}

void AutohostInterface::SendQuit()
{
	uchar msg = SERVER_QUIT;
	autohost.send(boost::asio::buffer(&msg, sizeof(uchar)));
}

void AutohostInterface::SendStartPlaying()
{
	uchar msg = SERVER_STARTPLAYING;
	autohost.send(boost::asio::buffer(&msg, sizeof(uchar)));
}

void AutohostInterface::SendGameOver()
{
	uchar msg = SERVER_GAMEOVER;
	autohost.send(boost::asio::buffer(&msg, sizeof(uchar)));
}

void AutohostInterface::SendPlayerJoined(uchar playerNum, const std::string& name)
{
	unsigned msgsize = 2*sizeof(uchar)+name.size();
	std::vector<boost::uint8_t> buffer(msgsize);
	buffer[0] = PLAYER_JOINED;
	buffer[1] = playerNum;
	strncpy((char*)(&buffer[2]), name.c_str(), name.size());
	autohost.send(boost::asio::buffer(buffer));
}

void AutohostInterface::SendPlayerLeft(uchar playerNum, uchar reason)
{
	uchar msg[3] = {PLAYER_LEFT, playerNum, reason};
	autohost.send(boost::asio::buffer(&msg, 3 * sizeof(uchar)));
}

void AutohostInterface::SendPlayerReady(uchar playerNum, uchar readyState)
{
	uchar msg[3] = {PLAYER_READY, playerNum, readyState};
	autohost.send(boost::asio::buffer(&msg, 3 * sizeof(uchar)));
}

void AutohostInterface::SendPlayerChat(uchar playerNum, uchar destination, const std::string& chatmsg)
{
	unsigned msgsize = 3*sizeof(uchar)+chatmsg.size();
	std::vector<boost::uint8_t> buffer(msgsize);
	buffer[0] = PLAYER_CHAT;
	buffer[1] = playerNum;
	buffer[2] = destination;
	strncpy((char*)(&buffer[3]), chatmsg.c_str(), chatmsg.size());
	autohost.send(boost::asio::buffer(buffer));
}

void AutohostInterface::SendPlayerDefeated(uchar playerNum)
{
	uchar msg[2] = {PLAYER_DEFEATED, playerNum};
	autohost.send(boost::asio::buffer(&msg, 2 * sizeof(uchar)));
}

void AutohostInterface::Message(const std::string& message)
{
	unsigned msgsize = sizeof(uchar) + message.size();
	std::vector<boost::uint8_t> buffer(msgsize);
	buffer[0] = SERVER_MESSAGE;
	strncpy((char*)(&buffer[1]), message.c_str(), message.size());
	autohost.send(boost::asio::buffer(buffer));
}

void AutohostInterface::Warning(const std::string& message)
{
	unsigned msgsize = sizeof(uchar) + message.size();
	std::vector<boost::uint8_t> buffer(msgsize);
	buffer[0] = SERVER_WARNING;
	strncpy((char*)(&buffer[1]), message.c_str(), message.size());
	autohost.send(boost::asio::buffer(buffer));
}

void AutohostInterface::SendLuaMsg(const boost::uint8_t* msg, size_t msgSize)
{
	std::vector<boost::uint8_t> buffer(msgSize+1);
	buffer[0] = GAME_LUAMSG;
	std::copy(msg, msg+msgSize, buffer.begin()+1);
	autohost.send(boost::asio::buffer(buffer));
}

void AutohostInterface::Send(const boost::uint8_t* msg, size_t msgSize)
{
	std::vector<boost::uint8_t> buffer(msgSize);
	std::copy(msg, msg+msgSize, buffer.begin());
	autohost.send(boost::asio::buffer(buffer));
}

std::string AutohostInterface::GetChatMessage()
{
	size_t bytes_avail = 0;
	if ((bytes_avail = autohost.available()) > 0)
	{
		std::vector<boost::uint8_t> buffer(bytes_avail+1, 0);
		size_t bytesReceived = autohost.receive(boost::asio::buffer(buffer));
		return std::string((char*)(&buffer[0]));
	}
	else
		return "";
}