1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2016 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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/>.
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"
42 #include "interface.h"
44 #include "mouse_listener.h"
51 using namespace NLMISC
;
52 using namespace NLNET
;
57 // -- -- random note: most of this needs to change completely anyway
63 CCallbackClient
*Connection
= NULL
;
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
)
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
);
97 addEntity(id
, name
, CEntity::Other
, startPosition
, startPosition
);
101 static void cbRemoveEntity (CMessage
&msgin
, TSockId from
, CCallbackNetBase
&netbase
)
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());
117 static void cbEntityPos (CMessage
&msgin
, TSockId from
, CCallbackNetBase
&netbase
)
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);
130 // receive my info, ignore them, i know where i am
134 EIT eit
= findEntity (id
, false);
135 if (eit
== Entities
.end ())
137 nlwarning ("can't find entity %u", id
);
141 CEntity
&entity
= (*eit
).second
;
143 entity
.ServerPosition
= position
;
144 entity
.AuxiliaryAngle
= angle
;
147 entity
.IsAiming
= true;
148 entity
.IsWalking
= false;
153 static void cbEntityTeleport(CMessage
&msgin
, TSockId from
, CCallbackNetBase
&netbase
)
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
);
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
)
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
);
192 playAnimation (entity
, HitAnim
, true);
198 static void cbSnowball (CMessage
&msgin
, TSockId from
, CCallbackNetBase
&netbase
)
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
)
218 static void cbIdentification (CMessage
&msgin
, TSockId from
, CCallbackNetBase
&netbase
)
223 // nlinfo ("my online id is %u", id);
226 // nlerror ("Self is NULL");
228 // if (Self->Id != id)
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
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);
245 // Self = &((*eit).second);
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
},
262 { "SNOWBALL", cbSnowball
},
263 { "IDENTIFICATION", cbIdentification
},
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");
289 string line
= Self
->Name
+ string("> ") + Line
;
290 msgout
.serial (line
);
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...
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);
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
);
340 fsaddr
= ConfigFile
->getVar("FSHost").asString ();
344 if(fsaddr
.find (":") == string::npos
)
349 CLoginCookie loginCookie
;
352 loginCookie
.setFromString (lc
);
355 string res
= CLoginClient::connectToShard (loginCookie
, fsaddr
, *Connection
);
358 string err
= string ("Connection to shard failed: ") + res
;
359 askString (err
, "", 2, CRGBA(64,0,0,128));
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
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 ();
421 } /* namespace SBCLIENT */