MsgPackUpdateTracker.cpp 5.84 KB
Newer Older
1
2
3
4
5
#include <arpa/inet.h>

#include "Bot.h"
#include "Food.h"

6
7
#include "config.h"

Thomas Kolb's avatar
Thomas Kolb committed
8
9
#include "MsgPackUpdateTracker.h"

10
11
/* Private methods */

12
void MsgPackUpdateTracker::appendMessage(const msgpack::sbuffer &buf)
13
{
14
	uint32_t length = htonl(static_cast<uint32_t>(buf.size()));
Thomas Kolb's avatar
Thomas Kolb committed
15

16
17
	m_stream.write(reinterpret_cast<char*>(&length), sizeof(length));
	m_stream.write(buf.data(), buf.size());
18
19
20
21
}

/* Public methods */

Thomas Kolb's avatar
Thomas Kolb committed
22
23
24
25
26
MsgPackUpdateTracker::MsgPackUpdateTracker()
{
	reset();
}

Hubert Denkmair's avatar
Hubert Denkmair committed
27
void MsgPackUpdateTracker::foodConsumed(const Food &food,
Thomas Kolb's avatar
Thomas Kolb committed
28
29
		const std::shared_ptr<Bot> &by_bot)
{
Hubert Denkmair's avatar
Hubert Denkmair committed
30
	m_foodConsumeMessage->items.push_back({food.getGUID(), by_bot->getGUID()});
Thomas Kolb's avatar
Thomas Kolb committed
31
32
}

Hubert Denkmair's avatar
Hubert Denkmair committed
33
void MsgPackUpdateTracker::foodDecayed(const Food &food)
Thomas Kolb's avatar
Thomas Kolb committed
34
{
Hubert Denkmair's avatar
Hubert Denkmair committed
35
	m_foodDecayMessage->food_ids.push_back(food.getGUID());
Thomas Kolb's avatar
Thomas Kolb committed
36
37
}

Hubert Denkmair's avatar
Hubert Denkmair committed
38
void MsgPackUpdateTracker::foodSpawned(const Food &food)
Thomas Kolb's avatar
Thomas Kolb committed
39
{
40
	m_foodSpawnMessage->new_food.push_back(food);
Thomas Kolb's avatar
Thomas Kolb committed
41
42
}

Thomas Kolb's avatar
Thomas Kolb committed
43
44
void MsgPackUpdateTracker::botSpawned(const std::shared_ptr<Bot> &bot)
{
45
46
47
48
49
50
	MsgPackProtocol::BotSpawnMessage msg;
	msg.bot = bot;

	msgpack::sbuffer buf;
	msgpack::pack(buf, msg);
	appendMessage(buf);
Thomas Kolb's avatar
Thomas Kolb committed
51
52
53
54
55
56
}

void MsgPackUpdateTracker::botKilled(
		const std::shared_ptr<Bot> &killer,
		const std::shared_ptr<Bot> &victim)
{
57
58
59
60
61
62
63
	MsgPackProtocol::BotKillMessage msg;
	msg.killer_id = killer->getGUID();
	msg.victim_id = victim->getGUID();

	msgpack::sbuffer buf;
	msgpack::pack(buf, msg);
	appendMessage(buf);
64
65
66
67
68
69
70
71
72
73

	if (msg.killer_id == msg.victim_id)
	{
		botLogMessage(victim->getViewerKey(), std::string("reset."));
	}
	else
	{
		botLogMessage(killer->getViewerKey(), std::string("you killed ") + victim->getName() + std::string("."));
		botLogMessage(victim->getViewerKey(), std::string("you were killed by ") + killer->getName() + std::string("."));
	}
Thomas Kolb's avatar
Thomas Kolb committed
74
75
}

76
77
void MsgPackUpdateTracker::botMoved(const std::shared_ptr<Bot> &bot, std::size_t steps)
{
78
	// Fill BotMoveMessage
79
	MsgPackProtocol::BotMoveItem item;
80
81
82

	const Snake::SegmentList &segments = bot->getSnake()->getSegments();

83
84
85
86
	item.bot_id = bot->getGUID();
	item.new_segments.assign(segments.begin(), segments.begin() + steps);
	item.current_segment_radius = bot->getSnake()->getSegmentRadius();
	item.current_length = segments.size();
87

88
	m_botMoveMessage->items.push_back(item);
89
90
91
92
93
94
95
96
97

	// Fill BotMoveHeadMessage
	MsgPackProtocol::BotMoveHeadItem headItem;

	headItem.bot_id = bot->getGUID();
	headItem.mass = bot->getSnake()->getMass();
	headItem.new_head_positions = bot->getSnake()->getHeadPositionsDuringLastMove();

	m_botMoveHeadMessage->items.push_back(headItem);
98
99
}

Hubert Denkmair's avatar
Hubert Denkmair committed
100
101
102
103
104
void MsgPackUpdateTracker::botLogMessage(uint64_t viewerKey, const std::string& message)
{
	m_botLogMessage->items.push_back({viewerKey, message});
}

105
106
void MsgPackUpdateTracker::gameInfo(void)
{
107
	MsgPackProtocol::GameInfoMessage msg;
108

109
110
	msg.world_size_x         = config::FIELD_SIZE_X;
	msg.world_size_y         = config::FIELD_SIZE_Y;
111
	msg.food_decay_per_frame = config::FOOD_DECAY_STEP;
112

113
114
115
116
117
	msg.snake_distance_per_step         = config::SNAKE_DISTANCE_PER_STEP;
	msg.snake_segment_distance_factor   = config::SNAKE_SEGMENT_DISTANCE_FACTOR;
	msg.snake_segment_distance_exponent = config::SNAKE_SEGMENT_DISTANCE_EXPONENT;
	msg.snake_pull_factor               = config::SNAKE_PULL_FACTOR;

118
119
120
	msgpack::sbuffer buf;
	msgpack::pack(buf, msg);
	appendMessage(buf);
121
122
}

123
void MsgPackUpdateTracker::worldState(Field& field)
124
{
125
	MsgPackProtocol::WorldUpdateMessage msg;
126

127
	msg.bots = field.getBots();
128

Hubert Denkmair's avatar
Hubert Denkmair committed
129
	msg.food.reserve(1024);
130
	for (auto& food: field.getFoodMap()) // TODO directly serialize FoodMap
131
	{
Hubert Denkmair's avatar
Hubert Denkmair committed
132
		msg.food.push_back(food);
133
	}
134

135
136
137
	msgpack::sbuffer buf;
	msgpack::pack(buf, msg);
	appendMessage(buf);
138
139
}

Hubert Denkmair's avatar
Hubert Denkmair committed
140
141
142
143
144
145
146
147
148
void MsgPackUpdateTracker::tick(uint64_t frame_id)
{
	MsgPackProtocol::TickMessage msg;
	msg.frame_id = frame_id;
	msgpack::sbuffer buf;
	msgpack::pack(buf, msg);
	appendMessage(buf);
}

149
150
151
152
153
154
155
156
void MsgPackUpdateTracker::botStats(const std::shared_ptr<Bot> &bot)
{
	MsgPackProtocol::BotStatsItem item;

	item.bot_id = bot->getGUID();
	item.natural_food_consumed = bot->getConsumedNaturalFood();
	item.carrison_food_consumed = bot->getConsumedFoodHuntedByOthers();
	item.hunted_food_consumed = bot->getConsumedFoodHuntedBySelf();
Thomas Kolb's avatar
Thomas Kolb committed
157
	item.mass = bot->getSnake()->getMass();
158
159
160
161

	m_botStatsMessage->items.push_back(item);
}

162
std::string MsgPackUpdateTracker::serialize(void)
Thomas Kolb's avatar
Thomas Kolb committed
163
{
164
	// decayed food
165
166
167
168
	if(!m_foodDecayMessage->food_ids.empty()) {
		msgpack::sbuffer buf;
		msgpack::pack(buf, m_foodDecayMessage);
		appendMessage(buf);
Thomas Kolb's avatar
Thomas Kolb committed
169
	}
170
171

	// spawned food
172
173
174
175
	if(!m_foodSpawnMessage->new_food.empty()) {
		msgpack::sbuffer buf;
		msgpack::pack(buf, m_foodSpawnMessage);
		appendMessage(buf);
Thomas Kolb's avatar
Thomas Kolb committed
176
177
178
	}

	// consumed food
179
180
181
182
	if(!m_foodConsumeMessage->items.empty()) {
		msgpack::sbuffer buf;
		msgpack::pack(buf, m_foodConsumeMessage);
		appendMessage(buf);
Thomas Kolb's avatar
Thomas Kolb committed
183
	}
184

185
	// moved bots
186
187
188
189
	if(!m_botMoveMessage->items.empty()) {
		msgpack::sbuffer buf;
		msgpack::pack(buf, m_botMoveMessage);
		appendMessage(buf);
190
191
	}

192
193
194
195
196
197
198
	// moved bots (compressed version)
	if(!m_botMoveHeadMessage->items.empty()) {
		msgpack::sbuffer buf;
		msgpack::pack(buf, m_botMoveHeadMessage);
		appendMessage(buf);
	}

199
200
201
202
203
204
205
	// bot statistics
	if(!m_botStatsMessage->items.empty()) {
		msgpack::sbuffer buf;
		msgpack::pack(buf, m_botStatsMessage);
		appendMessage(buf);
	}

Hubert Denkmair's avatar
Hubert Denkmair committed
206
207
208
209
210
211
212
	// log messages
	if (!m_botLogMessage->items.empty()) {
		msgpack::sbuffer buf;
		msgpack::pack(buf, m_botLogMessage);
		appendMessage(buf);
	}

213
214
215
	std::string result = m_stream.str();
	reset();
	return result;
Thomas Kolb's avatar
Thomas Kolb committed
216
217
218
219
}

void MsgPackUpdateTracker::reset(void)
{
220
221
222
223
	m_foodConsumeMessage = std::make_unique<MsgPackProtocol::FoodConsumeMessage>();
	m_foodSpawnMessage = std::make_unique<MsgPackProtocol::FoodSpawnMessage>();
	m_foodDecayMessage = std::make_unique<MsgPackProtocol::FoodDecayMessage>();
	m_botMoveMessage = std::make_unique<MsgPackProtocol::BotMoveMessage>();
224
	m_botMoveHeadMessage = std::make_unique<MsgPackProtocol::BotMoveHeadMessage>();
225
	m_botStatsMessage = std::make_unique<MsgPackProtocol::BotStatsMessage>();
Hubert Denkmair's avatar
Hubert Denkmair committed
226
	m_botLogMessage = std::make_unique<MsgPackProtocol::BotLogMessage>();
227

Thomas Kolb's avatar
Thomas Kolb committed
228
229
	m_stream.str("");
}
230