1 //  SuperTuxKart - a fun racing game with go-kart
2 //  Copyright (C) 2015  Supertuxkart-Team
3 //
4 //  This program is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU General Public License
6 //  as published by the Free Software Foundation; either version 3
7 //  of the License, or (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 
18 #include "network/protocols/game_protocol.hpp"
19 
20 #include "items/item_manager.hpp"
21 #include "items/network_item_manager.hpp"
22 #include "karts/abstract_kart.hpp"
23 #include "karts/controller/player_controller.hpp"
24 #include "modes/world.hpp"
25 #include "network/event.hpp"
26 #include "network/network_config.hpp"
27 #include "network/game_setup.hpp"
28 #include "network/network.hpp"
29 #include "network/network_config.hpp"
30 #include "network/network_string.hpp"
31 #include "network/protocol_manager.hpp"
32 #include "network/rewind_info.hpp"
33 #include "network/rewind_manager.hpp"
34 #include "network/socket_address.hpp"
35 #include "network/stk_host.hpp"
36 #include "network/stk_peer.hpp"
37 #include "tracks/track.hpp"
38 #include "utils/log.hpp"
39 #include "utils/time.hpp"
40 #include "main_loop.hpp"
41 
42 // ============================================================================
43 std::weak_ptr<GameProtocol> GameProtocol::m_game_protocol[PT_COUNT];
44 // ============================================================================
createInstance()45 std::shared_ptr<GameProtocol> GameProtocol::createInstance()
46 {
47     if (!emptyInstance())
48     {
49         Log::fatal("GameProtocol", "Create only 1 instance of GameProtocol!");
50         return NULL;
51     }
52     auto gm = std::make_shared<GameProtocol>();
53     ProcessType pt = STKProcess::getType();
54     m_game_protocol[pt] = gm;
55     return gm;
56 }   // createInstance
57 
58 //-----------------------------------------------------------------------------
59 /** Constructor. Allocates the buffer for events to send to the server. */
GameProtocol()60 GameProtocol::GameProtocol()
61             : Protocol(PROTOCOL_CONTROLLER_EVENTS)
62 {
63     m_network_item_manager = static_cast<NetworkItemManager*>
64         (Track::getCurrentTrack()->getItemManager());
65     m_data_to_send = getNetworkString();
66 }   // GameProtocol
67 
68 //-----------------------------------------------------------------------------
~GameProtocol()69 GameProtocol::~GameProtocol()
70 {
71     delete m_data_to_send;
72 }   // ~GameProtocol
73 
74 //-----------------------------------------------------------------------------
75 /** Synchronous update - will send all commands collected during the last
76  *  frame (and could optional only send messages every N frames).
77  */
sendActions()78 void GameProtocol::sendActions()
79 {
80     if (m_all_actions.size() == 0) return;   // nothing to do
81 
82     // Clear left-over data from previous frame. This way the network
83     // string will increase till it reaches maximum size necessary
84     m_data_to_send->clear();
85     if (m_all_actions.size() > 255)
86     {
87         Log::warn("GameProtocol",
88             "Too many actions unsent %d.", (int)m_all_actions.size());
89         m_all_actions.resize(255);
90     }
91     m_data_to_send->addUInt8(GP_CONTROLLER_ACTION)
92                    .addUInt8(uint8_t(m_all_actions.size()));
93 
94     // Add all actions
95     for (auto& a : m_all_actions)
96     {
97         if (Network::m_connection_debug)
98         {
99             Log::verbose("GameProtocol",
100                 "Controller action: %d %d %d %d %d %d",
101                 a.m_ticks, a.m_kart_id, a.m_action, a.m_value, a.m_value_l,
102                 a.m_value_r);
103         }
104         m_data_to_send->addUInt32(a.m_ticks);
105         m_data_to_send->addUInt8(a.m_kart_id);
106         const auto& c = compressAction(a);
107         m_data_to_send->addUInt8(std::get<0>(c)).addUInt16(std::get<1>(c))
108             .addUInt16(std::get<2>(c)).addUInt16(std::get<3>(c));
109     }   // for a in m_all_actions
110 
111     // FIXME: for now send reliable
112     sendToServer(m_data_to_send, /*reliable*/ true);
113     m_all_actions.clear();
114 }   // sendActions
115 
116 //-----------------------------------------------------------------------------
117 /** Called when a message from a remote GameProtocol is received.
118  */
notifyEventAsynchronous(Event * event)119 bool GameProtocol::notifyEventAsynchronous(Event* event)
120 {
121     if(!checkDataSize(event, 1)) return true;
122 
123     // Ignore events arriving when client has already exited
124     auto lock = acquireWorldDeletingMutex();
125     if (!World::getWorld())
126         return true;
127 
128     NetworkString &data = event->data();
129     uint8_t message_type = data.getUInt8();
130     switch (message_type)
131     {
132     case GP_CONTROLLER_ACTION: handleControllerAction(event); break;
133     case GP_STATE:             handleState(event);            break;
134     case GP_ITEM_CONFIRMATION: handleItemEventConfirmation(event); break;
135     case GP_ADJUST_TIME:
136     case GP_ITEM_UPDATE:
137         break;
138     default: Log::error("GameProtocol",
139                         "Received unknown message type %d - ignored.",
140                         message_type);                        break;
141     }   // switch message_type
142     return true;
143 }   // notifyEventAsynchronous
144 
145 //-----------------------------------------------------------------------------
146 /** Called from the local kart controller when an action (like steering,
147  *  acceleration, ...) was triggered. It sends a message with the new info
148  *  to the server and informs the rewind manager to store the event.
149  *  \param Kart id that triggered the action.
150  *  \param action Which action was triggered.
151  *  \param value New value for the given action.
152  */
controllerAction(int kart_id,PlayerAction action,int value,int val_l,int val_r)153 void GameProtocol::controllerAction(int kart_id, PlayerAction action,
154                                     int value, int val_l, int val_r)
155 {
156     // Store the action in the list of actions that will be sent to the
157     // server next.
158     assert(NetworkConfig::get()->isClient());
159     Action a;
160     a.m_kart_id = kart_id;
161     a.m_action  = action;
162     a.m_value   = value;
163     a.m_value_l = val_l;
164     a.m_value_r = val_r;
165     a.m_ticks   = World::getWorld()->getTicksSinceStart();
166 
167     m_all_actions.push_back(a);
168     const auto& c = compressAction(a);
169     // Store the event in the rewind manager, which is responsible
170     // for freeing the allocated memory
171     BareNetworkString *s = new BareNetworkString(4);
172     s->addUInt8(kart_id).addUInt8(std::get<0>(c)).addUInt16(std::get<1>(c))
173         .addUInt16(std::get<2>(c)).addUInt16(std::get<3>(c));
174 
175     RewindManager::get()->addEvent(this, s, /*confirmed*/true,
176                                    World::getWorld()->getTicksSinceStart());
177 }   // controllerAction
178 
179 // ----------------------------------------------------------------------------
180 /** Called when a controller event is received - either on the server from
181  *  a client, or on a client from the server. It sorts the event into the
182  *  RewindManager's network event queue. The server will also send this
183  *  event immediately to all clients (except to the original sender).
184  */
handleControllerAction(Event * event)185 void GameProtocol::handleControllerAction(Event *event)
186 {
187     STKPeer* peer = event->getPeer();
188     if (NetworkConfig::get()->isServer() && (peer->isWaitingForGame() ||
189         peer->getAvailableKartIDs().empty()))
190         return;
191     NetworkString &data = event->data();
192     uint8_t count = data.getUInt8();
193     bool will_trigger_rewind = false;
194     //int rewind_delta = 0;
195     int cur_ticks = 0;
196     const int not_rewound = RewindManager::get()->getNotRewoundWorldTicks();
197     for (unsigned int i = 0; i < count; i++)
198     {
199         cur_ticks = data.getUInt32();
200         // Since this is running in a thread, it might be called during
201         // a rewind, i.e. with an incorrect world time. So the event
202         // time needs to be compared with the World time independent
203         // of any rewinding.
204         if (cur_ticks < not_rewound && !will_trigger_rewind)
205         {
206             will_trigger_rewind = true;
207             //rewind_delta = not_rewound - cur_ticks;
208         }
209         uint8_t kart_id = data.getUInt8();
210         if (NetworkConfig::get()->isServer() &&
211             !peer->availableKartID(kart_id))
212         {
213             Log::warn("GameProtocol", "Wrong kart id %d from %s.",
214                 kart_id, peer->getAddress().toString().c_str());
215             return;
216         }
217 
218         uint8_t w = data.getUInt8();
219         uint16_t x = data.getUInt16();
220         uint16_t y = data.getUInt16();
221         uint16_t z = data.getUInt16();
222         if (Network::m_connection_debug)
223         {
224             const auto& a = decompressAction(w, x, y, z);
225             Log::verbose("GameProtocol",
226                 "Controller action: %d %d %d %d %d %d",
227                 cur_ticks, kart_id, std::get<0>(a), std::get<1>(a),
228                 std::get<2>(a), std::get<3>(a));
229         }
230         BareNetworkString *s = new BareNetworkString(3);
231         s->addUInt8(kart_id).addUInt8(w).addUInt16(x).addUInt16(y)
232             .addUInt16(z);
233         RewindManager::get()->addNetworkEvent(this, s, cur_ticks);
234     }
235 
236     if (data.size() > 0)
237     {
238         Log::warn("GameProtocol",
239                   "Received invalid controller data - remains %d",data.size());
240     }
241     if (NetworkConfig::get()->isServer())
242     {
243         // Send update to all clients except the original sender if the event
244         // is after the server time
245         peer->updateLastActivity();
246         if (!will_trigger_rewind)
247             STKHost::get()->sendPacketExcept(peer, &data, false);
248     }   // if server
249 
250 }   // handleControllerAction
251 
252 // ----------------------------------------------------------------------------
253 /** Sends a confirmation to the server that all item events up to 'ticks'
254  *  have been received.
255  *  \param ticks Up to which time in ticks the item events have been received.
256  */
sendItemEventConfirmation(int ticks)257 void GameProtocol::sendItemEventConfirmation(int ticks)
258 {
259     assert(NetworkConfig::get()->isClient());
260     NetworkString *ns = getNetworkString(5);
261     ns->addUInt8(GP_ITEM_CONFIRMATION).addUInt32(ticks);
262     // This message can be sent unreliable, it's not critical if it doesn't
263     // get delivered, a future update will come through
264     sendToServer(ns, /*reliable*/false);
265     delete ns;
266 }   // sendItemEventConfirmation
267 
268 // ----------------------------------------------------------------------------
269 /** Handles an item even confirmation from a client. Once it has been confirmed
270  *  that all clients have received certain events, those can be deleted and
271  *  do not need to be sent again.
272  *  \param event The data from the client.
273  */
handleItemEventConfirmation(Event * event)274 void GameProtocol::handleItemEventConfirmation(Event *event)
275 {
276     assert(NetworkConfig::get()->isServer());
277     int ticks = event->data().getTime();
278     m_network_item_manager->setItemConfirmationTime(event->getPeerSP(), ticks);
279 }   // handleItemEventConfirmation
280 
281 // ----------------------------------------------------------------------------
282 /** Called by the server before assembling a new message containing the full
283  *  state of the race to be sent to a client.
284  */
startNewState()285 void GameProtocol::startNewState()
286 {
287     assert(NetworkConfig::get()->isServer());
288     m_data_to_send->clear();
289     m_data_to_send->addUInt8(GP_STATE)
290         .addUInt32(World::getWorld()->getTicksSinceStart());
291 }   // startNewState
292 
293 // ----------------------------------------------------------------------------
294 /** Called by a server to add data to the current state. The data in buffer
295  *  is copied, so the data can be freed after this call/.
296  *  \param buffer Adds the data in the buffer to the current state.
297  */
addState(BareNetworkString * buffer)298 void GameProtocol::addState(BareNetworkString *buffer)
299 {
300     assert(NetworkConfig::get()->isServer());
301     m_data_to_send->addUInt16(buffer->size());
302     (*m_data_to_send) += *buffer;
303 }   // addState
304 
305 // ----------------------------------------------------------------------------
306 /** Called by a server to finalize the current state, which add updated
307  *  names of rewinder using to the beginning of state buffer
308  *  \param cur_rewinder List of current rewinder using.
309  */
finalizeState(std::vector<std::string> & cur_rewinder)310 void GameProtocol::finalizeState(std::vector<std::string>& cur_rewinder)
311 {
312     assert(NetworkConfig::get()->isServer());
313     auto& buffer = m_data_to_send->getBuffer();
314     auto pos = buffer.begin() + 1/*protocol type*/ + 1 /*gp event type*/+
315         4/*time*/;
316 
317     m_data_to_send->reset();
318     std::vector<uint8_t> names;
319     names.push_back((uint8_t)cur_rewinder.size());
320     for (std::string& name : cur_rewinder)
321     {
322         names.push_back((uint8_t)name.size());
323         std::vector<uint8_t> rewinder(name.begin(), name.end());
324         names.insert(names.end(), rewinder.begin(), rewinder.end());
325     }
326     buffer.insert(pos, names.begin(), names.end());
327 }   // finalizeState
328 
329 // ----------------------------------------------------------------------------
330 /** Called when the last state information has been added and the message
331  *  can be sent to the clients.
332  */
sendState()333 void GameProtocol::sendState()
334 {
335     assert(NetworkConfig::get()->isServer());
336     sendMessageToPeers(m_data_to_send, /*reliable*/false);
337 }   // sendState
338 
339 // ----------------------------------------------------------------------------
340 /** Called when a new full state is received form the server.
341  */
handleState(Event * event)342 void GameProtocol::handleState(Event *event)
343 {
344     if (!NetworkConfig::get()->isClient())
345         return;
346     NetworkString &data = event->data();
347     int ticks          = data.getUInt32();
348 
349     // Check for updated rewinder using
350     unsigned rewinder_size = data.getUInt8();
351     std::vector<std::string> rewinder_using;
352     for (unsigned i = 0; i < rewinder_size; i++)
353     {
354         std::string name;
355         data.decodeString(&name);
356         rewinder_using.push_back(name);
357     }
358 
359     // The memory for bns will be handled in the RewindInfoState object
360     RewindInfoState* ris = new RewindInfoState(ticks, data.getCurrentOffset(),
361         rewinder_using, data.getBuffer());
362     RewindManager::get()->addNetworkRewindInfo(ris);
363 }   // handleState
364 
365 // ----------------------------------------------------------------------------
366 /** Called from the RewindManager when rolling back.
367  *  \param buffer Pointer to the saved state information.
368  */
undo(BareNetworkString * buffer)369 void GameProtocol::undo(BareNetworkString *buffer)
370 {
371 
372 }   // undo
373 
374 // ----------------------------------------------------------------------------
375 /** Called from the RewindManager after a rollback to replay the stored
376  *  events.
377  *  \param buffer Pointer to the saved state information.
378  */
rewind(BareNetworkString * buffer)379 void GameProtocol::rewind(BareNetworkString *buffer)
380 {
381     int kart_id = buffer->getUInt8();
382     uint8_t w = buffer->getUInt8();
383     uint16_t x = buffer->getUInt16();
384     uint16_t y = buffer->getUInt16();
385     uint16_t z = buffer->getUInt16();
386     const auto& a = decompressAction(w, x, y, z);
387     Controller *c = World::getWorld()->getKart(kart_id)->getController();
388     PlayerController *pc = dynamic_cast<PlayerController*>(c);
389     // This can be endcontroller when finishing the race
390     if (pc)
391     {
392         pc->actionFromNetwork(std::get<0>(a), std::get<1>(a), std::get<2>(a),
393             std::get<3>(a));
394     }
395 }   // rewind
396 
397 // ----------------------------------------------------------------------------
update(int ticks)398 void GameProtocol::update(int ticks)
399 {
400     if (!World::getWorld())
401         ProtocolManager::lock()->findAndTerminate(PROTOCOL_CONTROLLER_EVENTS);
402 }   // update
403