Fix crash
[ryzomcore.git] / snowballs2 / client / src / network.cpp
blob8e194e52fcb39bbea895f0f77648e6478f9f001e
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2016 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 // Includes
24 #include <nel/misc/types_nl.h>
25 #include <nel/misc/event_listener.h>
26 #include <nel/misc/command.h>
27 #include <nel/misc/log.h>
28 #include <nel/misc/displayer.h>
29 #include <nel/misc/vectord.h>
31 #include <nel/net/login_client.h>
32 #include <nel/net/login_cookie.h>
34 #include <nel/3d/u_text_context.h>
36 #include <nel/pacs/u_move_primitive.h>
38 #include "snowballs_client.h"
39 #include "commands.h"
40 #include "network.h"
41 #include "entities.h"
42 #include "interface.h"
43 #include "graph.h"
44 #include "mouse_listener.h"
47 // Namespaces
50 using namespace std;
51 using namespace NLMISC;
52 using namespace NLNET;
53 using namespace NL3D;
55 namespace SBCLIENT {
57 // -- -- random note: most of this needs to change completely anyway
60 // Variables
63 CCallbackClient *Connection = NULL;
66 // Functions
69 static void cbClientDisconnected (TSockId from, void *arg)
71 nlwarning ("You lost the connection to the server");
73 askString ("You lost the connection to the server!!!", "", 2, CRGBA(64,0,0,128));
76 static void cbAddEntity (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
78 uint32 id;
79 string name;
80 uint8 race;
81 CVector startPosition;
83 msgin.serial (id, name, race, startPosition);
85 // nlinfo ("%s", stringFromVector (msgin.bufferAsVector()));
87 // nlinfo ("Receive add entity %u '%s' %s (%f,%f,%f)", id, name.c_str(), race==0?"penguin":"gnu", startPosition.x, startPosition.y, startPosition.z);
89 nlinfo ("New player named '%s' comes in at position (%8.2f, %8.2f, %8.2f)", name.c_str(), startPosition.x, startPosition.y, startPosition.z);
91 if (Self == NULL && name == Login.toUtf8())
93 addEntity(id, name, CEntity::Self, startPosition, startPosition);
95 else
97 addEntity(id, name, CEntity::Other, startPosition, startPosition);
101 static void cbRemoveEntity (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
103 uint32 id;
105 msgin.serial (id);
107 // nlinfo ("Receive remove entity %u", id);
109 EIT eit = findEntity (id);
110 CEntity &entity = (*eit).second;
112 nlinfo ("Player named '%s' goes offline", entity.Name.c_str());
114 removeEntity (id);
117 static void cbEntityPos (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
119 uint32 id;
120 CVector position;
121 float angle;
122 uint32 state;
124 msgin.serial (id, position, angle, state);
126 // nlinfo ("(%5d) Receive entity pos %u (%f,%f,%f) %f, %u", msgin.length(), id, position.x, position.y, position.z, angle, state);
128 if (Self->Id == id)
130 // receive my info, ignore them, i know where i am
131 return;
134 EIT eit = findEntity (id, false);
135 if (eit == Entities.end ())
137 nlwarning ("can't find entity %u", id);
139 else
141 CEntity &entity = (*eit).second;
143 entity.ServerPosition = position;
144 entity.AuxiliaryAngle = angle;
145 if (state&1)
147 entity.IsAiming = true;
148 entity.IsWalking = false;
153 static void cbEntityTeleport(CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
155 // temp
156 uint32 id;
157 CVector position;
158 msgin.serial(id, position);
159 nldebug("Received entity %u teleport %f,%f,%f", id, position.x, position.y, position.z);
160 EIT eit = findEntity(id, false);
161 if (eit == Entities.end()) nlwarning("can't find entity %u", id);
162 else
164 CEntity &entity = eit->second;
165 entity.ServerPosition = position;
166 entity.Position = position;
167 entity.MovePrimitive->setGlobalPosition(CVectorD(position.x, position.y, position.z), 0);
168 if (&entity == Self) MouseListener->setPosition(position);
172 static void cbHit(CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
174 uint32 sid, eid;
175 bool direct;
177 msgin.serial (sid, eid, direct);
179 // nlinfo ("Receive hit msg %u %u %d", sid, eid, direct);
181 EIT eit = findEntity (eid);
182 CEntity &entity = (*eit).second;
184 if (!entity.AnimQueue.empty())
186 EAnim a = entity.AnimQueue.front ();
187 playAnimation (entity, HitAnim, true);
188 playAnimation (entity, a);
190 else
192 playAnimation (entity, HitAnim, true);
195 removeEntity (sid);
198 static void cbSnowball (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
200 uint32 eid, sid;
201 CVector position, target;
202 float speed, deflagRadius;
204 msgin.serial (sid, eid, position, target, speed, deflagRadius);
206 // nlinfo ("Receive a snowball message");
208 shotSnowball (sid, eid, position, target, speed, deflagRadius);
211 static void cbChat (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
213 string line;
214 msgin.serial (line);
215 addLine (line);
218 static void cbIdentification (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
220 uint32 id;
221 msgin.serial (id);
223 // nlinfo ("my online id is %u", id);
225 // if (Self == NULL)
226 // nlerror ("Self is NULL");
228 // if (Self->Id != id)
229 // {
230 //// nlinfo ("remaping my entity from %u to %u", Self->Id, id);
232 // // copy my old entity
233 // CEntity me = *Self;
235 // // set my new online id
236 // me.Id = id;
238 // // add my new entity in the array
239 // EIT eit = (Entities.insert (make_pair (id, me))).first;
241 // // remove my old entity
242 // Entities.erase (Self->Id);
244 // // remap Self
245 // Self = &((*eit).second);
246 // }
248 // send to the network my entity
249 std::string login_name(Login.toUtf8());
250 sendAddEntity(id, login_name, 1);
253 // Array that contains all callback that could comes from the server
254 static TCallbackItem ClientCallbackArray[] =
256 { "ADD_ENTITY", cbAddEntity },
257 { "REMOVE_ENTITY", cbRemoveEntity },
258 { "ENTITY_POS", cbEntityPos },
259 { "ENTITY_TP", cbEntityTeleport },
260 { "HIT", cbHit },
261 { "CHAT", cbChat },
262 { "SNOWBALL", cbSnowball },
263 { "IDENTIFICATION", cbIdentification },
267 bool isOnline ()
269 return Connection != NULL && Connection->connected ();
272 void sendAddEntity (uint32 id, string &name, uint8 race)
274 if (!isOnline ()) return;
276 CMessage msgout("ADD_ENTITY");
277 msgout.serial(id, name, race);
278 Connection->send(msgout);
281 void sendChatLine (string Line)
283 if (!isOnline ()) return;
285 CMessage msgout ("CHAT");
286 string s;
287 if (Self != NULL)
289 string line = Self->Name + string("> ") + Line;
290 msgout.serial (line);
292 else
294 string line = string("Unknown> ") + Line;
295 msgout.serial (line);
298 Connection->send (msgout);
301 void sendEntityPos (CEntity &entity)
303 if (!isOnline ()) return;
305 // is aiming? is launching etc...
306 uint32 state = 0;
307 state |= (entity.IsAiming?1:0);
309 CMessage msgout ("ENTITY_POS");
310 msgout.serial (entity.Id, entity.Position, entity.Angle, state);
312 Connection->send (msgout);
314 // nlinfo("(%5d) Sending pos to network (%f,%f,%f, %f), %u", msgout.length(), entity.Position.x, entity.Position.y, entity.Position.z, entity.Angle, state);
317 void sendSnowBall (uint32 eid, const NLMISC::CVector &position, const NLMISC::CVector &target, float speed, float deflagRadius)
319 if (!isOnline ()) return;
321 CMessage msgout ("SNOWBALL");
322 msgout.serial (eid, const_cast<CVector &>(position), const_cast<CVector &>(target), speed, deflagRadius);
323 Connection->send (msgout);
325 // nlinfo("Sending snowball to network (%f,%f,%f) to (%f,%f,%f) with %f %f", position.x, position.y, position.z, target.x, target.y, target.z, speed, deflagRadius);
329 TTime LastPosSended;
331 void initNetwork(const std::string &lc, const std::string &addr)
333 // if lc and addr is valid, directly connect to the fs
334 Connection = new CCallbackClient;
335 Connection->addCallbackArray (ClientCallbackArray, sizeof (ClientCallbackArray) / sizeof (ClientCallbackArray[0]));
336 Connection->setDisconnectionCallback (cbClientDisconnected, NULL);
338 string fsaddr;
339 if (addr.empty())
340 fsaddr = ConfigFile->getVar("FSHost").asString ();
341 else
342 fsaddr = addr;
344 if(fsaddr.find (":") == string::npos)
346 fsaddr += ":37000";
349 CLoginCookie loginCookie;
350 if (!lc.empty ())
352 loginCookie.setFromString (lc);
355 string res = CLoginClient::connectToShard (loginCookie, fsaddr, *Connection);
356 if (!res.empty ())
358 string err = string ("Connection to shard failed: ") + res;
359 askString (err, "", 2, CRGBA(64,0,0,128));
361 else
363 // we remove all offline entities
364 removeAllEntitiesExceptUs ();
366 askString ("You are online!!!", "", 2, CRGBA(0,64,0,128));
367 // now we have to wait the identification message to know my id
370 LastPosSended = 0;
373 void updateNetwork()
375 if (Connection != NULL)
377 Connection->update ();
379 sint64 newBytesDownloaded = (sint64) Connection->newBytesDownloaded ();
380 sint64 newBytesUploaded = (sint64) Connection->newBytesUploaded ();
382 TextContext->setHotSpot (UTextContext::MiddleTop);
383 TextContext->setColor (CRGBA(255, 255, 255, 255));
384 TextContext->setFontSize (14);
385 TextContext->printfAt (0.5f, 0.99f, "d:%" NL_I64 "u u:%" NL_I64 "u / d:%" NL_I64 "u u:%" NL_I64 "u / d:%" NL_I64 "u u:%" NL_I64 "u",
386 Connection->bytesDownloaded (), Connection->bytesUploaded (),
387 Connection->getBytesReceived (),Connection->getBytesSent (),
388 newBytesDownloaded, newBytesUploaded);
390 DownloadGraph.addValue ((float)newBytesDownloaded);
391 UploadGraph.addValue ((float)newBytesUploaded);
393 if (isOnline () && Self != NULL)
395 static float oldAngle = 0.0f;
397 if ((Self->Angle != oldAngle || Self->IsAiming || Self->IsWalking) && CTime::getLocalTime () > LastPosSended + 100)
399 sendEntityPos (*Self);
401 LastPosSended = CTime::getLocalTime ();
403 oldAngle = Self->Angle;
409 void releaseNetwork()
411 if (Connection != NULL)
413 if (Connection->connected ())
414 Connection->disconnect ();
416 delete Connection;
417 Connection = NULL;
421 } /* namespace SBCLIENT */
423 /* end of file */