Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/entity.cc33
-rw-r--r--src/core/entity.h14
-rw-r--r--src/core/gameconnection.cc2
-rw-r--r--src/core/netconnection.cc245
-rw-r--r--src/core/netconnection.h5
-rw-r--r--src/core/netserver.cc130
6 files changed, 259 insertions, 170 deletions
diff --git a/src/core/entity.cc b/src/core/entity.cc
index ece1e9b..aa9e45b 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -112,13 +112,13 @@ void Entity::list()
/* ---- class Entity ----------------------------------------------- */
-Entity::Entity(const unsigned int flags) :
+Entity::Entity() :
entity_location(0.0f, 0.0f, 0.0f),
entity_color(1.0f, 1.0f, 1.0f, 1.0f),
entity_color_second(1.0f, 1.0f, 1.0f, 1.0f)
{
entity_id = 0;
- entity_flags = flags;
+ entity_flags = 0;
entity_moduletypeid = 0;
entity_speed = 0.0f;
@@ -391,15 +391,13 @@ void Entity::remove_menu(std::string const &label)
/* ---- class EntityDynamic ---------------------------------------- */
-EntityDynamic::EntityDynamic(unsigned int flags) :
- Entity(flags)
+EntityDynamic::EntityDynamic() : Entity()
{
entity_state = Normal;
entity_timer = 0;
}
-EntityDynamic::EntityDynamic(std::istream & is) :
- Entity(is)
+EntityDynamic::EntityDynamic(std::istream & is) : Entity(is)
{
entity_state = Normal;
entity_timer = 0;
@@ -507,8 +505,7 @@ void EntityDynamic::receive_server_update(std::istream &is)
/*----- EntityControlable ------------------------------------------ */
-EntityControlable::EntityControlable(Player *owner, unsigned int flags) :
- EntityDynamic(flags)
+EntityControlable::EntityControlable() : EntityDynamic()
{
entity_thrust = 0;
entity_movement = 0;
@@ -521,8 +518,6 @@ EntityControlable::EntityControlable(Player *owner, unsigned int flags) :
target_afterburner = 0.0f;
entity_owner = 0;
- if (owner)
- owner->add_asset(this);
}
EntityControlable::EntityControlable(std::istream & is) :
@@ -548,6 +543,18 @@ EntityControlable::~EntityControlable()
entity_owner->remove_asset(this);
}
+void EntityControlable::set_owner(Player *owner)
+{
+ if (entity_owner)
+ entity_owner->remove_asset(this);
+
+ entity_owner = owner;
+
+ if (entity_owner)
+ entity_owner->add_asset(this);
+
+}
+
void EntityControlable::serialize_server_create(std::ostream & os) const
{
EntityDynamic::serialize_server_create(os);
@@ -696,16 +703,14 @@ void EntityControlable::set_afterburner(float afterburner)
/*----- EntityGlobe ------------------------------------------------ */
-EntityGlobe::EntityGlobe(unsigned int flags) :
- Entity(flags)
+EntityGlobe::EntityGlobe() : Entity()
{
render_texture = 0;
entity_rotationspeed = 0;
entity_shape = Sphere;
}
-EntityGlobe::EntityGlobe(std::istream & is) :
- Entity(is)
+EntityGlobe::EntityGlobe(std::istream & is) : Entity(is)
{
render_texture = 0;
entity_rotationspeed = 0;
diff --git a/src/core/entity.h b/src/core/entity.h
index ae2585d..1bc93a1 100644
--- a/src/core/entity.h
+++ b/src/core/entity.h
@@ -56,7 +56,7 @@ public:
typedef std::list<MenuDescription *> Menus;
/// create a new entity and add it to the registry
- Entity(const unsigned int flags = 0);
+ Entity();
/// create an entity from stream data
Entity(std::istream & is);
@@ -413,7 +413,7 @@ class EntityDynamic : public Entity
{
public:
/// create a dynamic entity
- EntityDynamic(const unsigned int flags = 0);
+ EntityDynamic();
/// create a dynamic entity from stream data
EntityDynamic(std::istream & is);
@@ -479,8 +479,8 @@ class EntityControlable : public EntityDynamic
{
friend class Player;
public:
- /// create a controlable entity
- EntityControlable(Player *owner, const unsigned int flags = 0);
+ /// server-side constructor, create a controlable entity
+ EntityControlable();
/// create a controlable entity from stream data
EntityControlable(std::istream & is);
@@ -531,6 +531,9 @@ public:
/// receive a server-to-client update from a stream
virtual void receive_server_update(std::istream &is);
+ /// set the player who owns this entity
+ void set_owner(Player *owner);
+
/// set the target thrust
void set_thrust(float thrust);
@@ -591,7 +594,8 @@ private:
class EntityGlobe : public Entity
{
public:
- EntityGlobe(const unsigned int flags = 0);
+ /// server-side constructor
+ EntityGlobe();
EntityGlobe(std::istream & is);
virtual ~EntityGlobe();
diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc
index f0dfbc6..0da1803 100644
--- a/src/core/gameconnection.cc
+++ b/src/core/gameconnection.cc
@@ -205,7 +205,7 @@ void GameConnection::frame(unsigned long timestamp)
if (connection_network->state() == NetConnection::Connected) {
if (localcontrol() && localcontrol()->dirty()) {
- connection_network->send_clientupdate(localcontrol());
+ connection_network->send_client_update(localcontrol());
localcontrol()->set_dirty(false);
}
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc
index 1318467..0a816b8 100644
--- a/src/core/netconnection.cc
+++ b/src/core/netconnection.cc
@@ -356,7 +356,7 @@ void NetConnection::send_playerinfo()
}
// send a "cup" client update message to the server
-void NetConnection::send_clientupdate(Entity *entity)
+void NetConnection::send_client_update(Entity *entity)
{
// cup <id> <entity data>
std::ostringstream msg;
@@ -366,6 +366,15 @@ void NetConnection::send_clientupdate(Entity *entity)
this->send_raw(msg.str());
}
+// send a "req" entity request
+void NetConnection::send_entity_request(Entity *entity)
+{
+ // req <id>
+ std::ostringstream msg;
+ msg << "req " << entity->id() << '\n';
+ this->send_raw(msg.str());
+}
+
// send a "cmd" command line message to the server
void NetConnection::send_command(std::string const &cmdline)
{
@@ -440,12 +449,12 @@ void NetConnection::send_info_request(Info *info)
* msg rcon <text>
* msg snd <soundname>
* die <id>
- * ent <id>
+ * ent <id> <typeid>
* frame
- * sup <id>
+ * sup <id> <typeid>
* pif <id>
* pid <id>
- * inf <id>
+ * inf <id> <typelabel> <label>
* zone
*/
void NetConnection::parse_incoming_message(const std::string & message)
@@ -455,7 +464,126 @@ void NetConnection::parse_incoming_message(const std::string & message)
std::string command;
msgstream >> command;
- if (command == "msg") {
+ if (command.compare("sup") == 0) {
+
+ // entity server update: sup <id> <typeid>
+ if (connection_state == Connected) {
+ unsigned int type;
+ unsigned int id;
+
+ if ((msgstream >> id) && (msgstream >> type)) {
+ if (!id) {
+ return;
+ }
+
+ Entity *entity = Entity::find(id);
+ if (entity) {
+ // validate entity type
+ if (entity->type() != type) {
+ // type mismatch, delete the entity
+ if (localcontrol() == entity)
+ localplayer()->set_control(0);
+
+ Entity::erase(id);
+ entity = 0;
+ }
+ }
+
+ if (!entity) {
+ switch (type) {
+ case Entity::Default:
+ entity = new Entity(msgstream);
+ break;
+ case Entity::Dynamic:
+ entity = new EntityDynamic(msgstream);
+ break;
+ case Entity::Controlable:
+ entity = new EntityControlable(msgstream);
+ break;
+ case Entity::Globe:
+ entity = new EntityGlobe(msgstream);
+ break;
+ default:
+ con_warn << "Received update for unknown entity type " << type << "!" << std::endl;
+ return;
+ break;
+ }
+
+ Entity::add(entity, id);
+ send_entity_request(entity);
+ }
+
+ // receive update
+ entity->receive_server_update(msgstream);
+ }
+ }
+
+ } else if (command.compare("ent") == 0) {
+ // entity create message
+ unsigned int type = 0;
+ unsigned int id = 0;
+
+ if ((msgstream >> id) && (msgstream >> type)) {
+
+ if (!id) {
+ con_warn << "Received create for NULL entity!" << std::endl;
+ return;
+ }
+ //con_debug << "Received create entity id " << id << " type " << type << std::endl;
+
+ Entity *entity = Entity::find(id);
+
+ if (entity) {
+ // validate entity type
+ if (entity->type() != type) {
+ // type mismatch, delete the entity
+ if (localcontrol() == entity)
+ localplayer()->set_control(0);
+ Entity::erase(id);
+ entity = 0;
+ }
+ }
+
+ if (!entity) {
+ switch (type) {
+ case Entity::Default:
+ entity = new Entity(msgstream);
+ break;
+ case Entity::Dynamic:
+ entity = new EntityDynamic(msgstream);
+ break;
+ case Entity::Controlable:
+ entity = new EntityControlable(msgstream);
+ break;
+ case Entity::Globe:
+ entity = new EntityGlobe(msgstream);
+ break;
+ default:
+ con_warn << "Received create for unknown entity type " << type << "!" << std::endl;
+ return;
+ break;
+ }
+ Entity::add(entity, id);
+ }
+
+ entity->receive_server_create(msgstream);
+ }
+
+ } else if (command.compare("die") == 0) {
+
+ unsigned int id;
+ if (msgstream >> id) {
+ //con_debug << "Received die entity id " << id << std::endl;
+ Entity *e = Entity::find(id);
+ if (localcontrol() == e)
+ localplayer()->set_control(0);
+ if (e)
+ Entity::erase(id);
+ }
+
+ } else if (command.compare("msg") == 0) {
+
+ // text message: msg <level>
std::string level;
if (msgstream >> level) {
if (level == "info") {
@@ -482,7 +610,9 @@ void NetConnection::parse_incoming_message(const std::string & message)
}
}
}
- } else if (command == "connect") {
+
+ } else if (command.compare("connect") == 0) {
+
if (connection_state == Pending) {
send_playerinfo();
connection_state = Connected;
@@ -490,80 +620,30 @@ void NetConnection::parse_incoming_message(const std::string & message)
}
return;
- } else if (command == "disconnect") {
+ } else if (command.compare("disconnect") == 0) {
con_error << "Server disconnected!" << std::endl;
abort();
- } else if (command == "ping") {
+ } else if (command.compare("ping") == 0) {
+
unsigned long timestamp;
if ((msgstream >> timestamp)) {
send_ping_reply(timestamp);
}
- } else if (command == "frame") {
+ } else if (command.compare("frame") == 0) {
+
unsigned long timestamp;
if ((msgstream >> timestamp)) {
send_ping_reply(timestamp);
connection_timestamp = timestamp;
}
-
- } else if (command == "die") {
- unsigned int id;
- if (msgstream >> id) {
- //con_debug << "Received die entity id " << id << std::endl;
- Entity *e = Entity::find(id);
- if (localcontrol() == e)
- localplayer()->set_control(0);
- if (e)
- Entity::erase(id);
- }
-
- } else if (command == "ent") {
-
- unsigned int type = 0;
- unsigned int id = 0;
-
- if ((msgstream >> id) && (msgstream >> type)) {
-
- if (!id) {
- con_warn << "Received create for NULL entity!" << std::endl;
- return;
- }
- //con_debug << "Received create entity id " << id << " type " << type << std::endl;
-
- Entity *entity = Entity::find(id);
-
- if (!entity) {
- switch (type) {
- case Entity::Default:
- entity = new Entity(msgstream);
- break;
- case Entity::Dynamic:
- entity = new EntityDynamic(msgstream);
- break;
- case Entity::Controlable:
- entity = new EntityControlable(msgstream);
- break;
- case Entity::Globe:
- entity = new EntityGlobe(msgstream);
- break;
- default:
- con_warn << "Received create for unknown entity type " << type << "!" << std::endl;
- return;
- break;
- }
-
- Entity::add(entity, id);
- }
-
- entity->receive_server_create(msgstream);
- //game()->update_entity_clientstate(entity);
- }
-
- } else if (command == "menu") {
+
+ } else if (command.compare("menu") == 0) {
unsigned int id = 0;
+
if (msgstream >> id) {
if (!id) {
con_warn << "Received menu for NULL entity!" << std::endl;
@@ -614,7 +694,7 @@ void NetConnection::parse_incoming_message(const std::string & message)
connection()->localplayer()->set_control(0);
}
- } else if (command == "pif") {
+ } else if (command.compare("pif") == 0) {
//con_debug << "Received update player info" << std::endl;
int player_id;
@@ -671,7 +751,7 @@ void NetConnection::parse_incoming_message(const std::string & message)
player->set_dirty(false);
}
- } else if (command == "pid") {
+ } else if (command.compare("pid") == 0) {
con_debug << "Received player disconnect info" << std::endl;
int player_id;
@@ -694,8 +774,9 @@ void NetConnection::parse_incoming_message(const std::string & message)
return;
}
}
+
+ } else if (command.compare("inf") == 0) {
- } else if (command == "inf") {
// incoming info record
unsigned int id = 0;
std::string typelabelstr;
@@ -708,25 +789,25 @@ void NetConnection::parse_incoming_message(const std::string & message)
con_warn << "Received invalid info record message!" << std::endl;
return;
}
-
+
// read type label
n.clear();
while ((msgstream.get(c)) && (c != '"'));
while ((msgstream.get(c)) && (c != '"'))
n +=c;
-
- typelabelstr.assign(n);
+
+ typelabelstr.assign(n);
if (!typelabelstr.size()) {
con_warn << "Received invalid info record message!" << std::endl;
return;
}
-
+
// read info label
n.clear();
while ((msgstream.get(c)) && (c != '"'));
while ((msgstream.get(c)) && (c != '"'))
n +=c;
-
+
infolabelstr.assign(n);
if (!infolabelstr.size()) {
con_warn << "Received invalid info record message for type '" << typelabelstr << "'!" << std::endl;
@@ -742,7 +823,7 @@ void NetConnection::parse_incoming_message(const std::string & message)
// find the Info instance
Info *info = Info::find(id);
if (!info) {
- info = Info::find(infotype, infolabelstr);
+ info = Info::find(infotype, infolabelstr);
}
// create one if necessary
@@ -756,24 +837,6 @@ void NetConnection::parse_incoming_message(const std::string & message)
info->receive_server_update(msgstream);
info->clear_timestamp();
-
- } else if (command == "sup") {
-
- if (connection_state == Connected) {
- unsigned int id;
- if (msgstream >> id) {
- //con_debug << "Received update entity id " << id << std::endl;
- Entity *entity = Entity::find(id);
- if (!entity) {
- // FIXME request entity from the server
- con_warn << "Update for unknown entity " << id << "!" << std::endl;
- } else {
- // FIXME check of the received update matches the actual entity
- entity->receive_server_update(msgstream);
- }
- }
- }
-
}
}
diff --git a/src/core/netconnection.h b/src/core/netconnection.h
index 36cf154..99b8794 100644
--- a/src/core/netconnection.h
+++ b/src/core/netconnection.h
@@ -58,8 +58,11 @@ public:
void send_playerinfo();
/// send a client update message to the remote server
- void send_clientupdate(Entity *entity);
+ void send_client_update(Entity *entity);
+ /// send an entity request
+ void send_entity_request(Entity *entity);
+
/// send a chat message
void send_say(std::string const &text);
diff --git a/src/core/netserver.cc b/src/core/netserver.cc
index 65388e8..6ba9dc7 100644
--- a/src/core/netserver.cc
+++ b/src/core/netserver.cc
@@ -506,12 +506,12 @@ void NetServer::send_entity_delete(NetClient *client, Entity *entity)
}
}
-// broadcast a "sup" server update entity message to all clients
+// send a "sup" server update entity message to a client
void NetServer::send_entity_update(NetClient *client, Entity *entity)
{
if ((client->state() == NetClient::Connected) && !entity->serverside()) {
std::ostringstream msg;
- msg << "sup " << entity->id() << " ";
+ msg << "sup " << entity->id() << " " << entity->type() << " ";
entity->serialize_server_update(msg);
msg << '\n';
@@ -584,6 +584,8 @@ void NetServer::send_info_update(NetClient *client, Info *info)
* ping
* say <text>
* priv <player> <text>
+ * info <id> <typelabel> <label>
+ * req <id>
*
*/
void NetServer::parse_incoming_message(NetClient *client, const std::string & message)
@@ -596,15 +598,15 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
std::string command;
msgstream >> command;
- // disconnect
- if (command == "disconnect") {
+ if (command.compare("disconnect") == 0 ) {
+ // disconnect
client->abort();
return;
- }
-
- // connection request
- // connect is the first command expected from the client
- if (command == "connect") {
+
+ } else if (command.compare("connect") == 0) {
+ // connection request
+ // connect is the first command expected from the client
+
if (client->state() != NetClient::Connecting)
return;
@@ -631,11 +633,11 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
send_disconnect(client);
}
return;
- }
-
- // pif - update player information
- // client connection is completed on the first pif
- if (command == "pif") {
+
+ } else if (command.compare("pif") == 0) {
+ // pif - update player information
+ // client connection is completed on the first pif
+
std::string oldname(client->player()->name());
client->player()->receive_client_update(msgstream);
@@ -652,9 +654,8 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
netmsg.append(client->player()->name());
server()->broadcast(netmsg);
}
- }
-
- if (command == "ping") {
+
+ } else if (command.compare("ping") == 0) {
unsigned long timestamp;
if (msgstream >> timestamp) {
client->player()->set_ping(application()->timestamp() - server()->startup() - timestamp);
@@ -665,16 +666,63 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
if (client->state() != NetClient::Connected)
return;
- // cmd
- if (command == "cmd") {
+ if (command.compare("cmd") == 0) {
if (message.size() > command.size() + 1) {
std::string cmdline(message.substr(command.size() + 1));
server()->exec(client->player(), cmdline);
}
return;
- }
- if (command == "inf") {
+ } else if (command.compare("cup") == 0) {
+ // cup - client update entity
+
+ //con_debug << message << "\n";
+ unsigned int id;
+ if (msgstream >> id) {
+ Entity *entity = Entity::find(id);
+ if (!entity) {
+ con_warn << client->host() << ":" << client->port() << " update for unknown entity " << id << "\n";
+ return;
+ }
+
+ if (entity->type() != Entity::Controlable) {
+ con_warn << client->host() << ":" << client->port() << " update for non-controlable entity " << id << "\n";
+ return;
+ }
+
+ EntityControlable *entitycontrolable = (EntityControlable *)entity;
+
+ if (entitycontrolable->owner() != client->player()) {
+ con_warn << client->host() << ":" << client->port() << " update for non-owned entity " << id << "\n";
+ return;
+ }
+
+ entitycontrolable->set_dirty(true);
+ entitycontrolable->receive_client_update(msgstream);
+ }
+ return;
+
+ } else if (command.compare("req") == 0) {
+
+ // request entity
+ unsigned int id;
+
+ if (!(msgstream >> id)) {
+ con_warn << "^B" << client->player()->name() << "^W invalid entity request" << std::endl;
+ return;
+ }
+
+ Entity *entity = Entity::find(id);
+ if (entity) {
+ send_entity_create(client, entity);
+ } else {
+ con_warn << "^B" << client->player()->name() << "^W entity request for unkown entity " << id << std::endl;
+ }
+ return;
+
+ } else if (command.compare("inf") == 0) {
+
+ // request information record
unsigned int id;
if (!(msgstream >> id)) {
@@ -726,9 +774,8 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
send_info_update(client, info);
client->transmit();
}
- }
- if (command == "rcon") {
+ } else if (command.compare("rcon") == 0) {
if ((message.size() > command.size() + 1) && Cvar::sv_password->str().size()) {
if ((Cvar::sv_password->str().compare(client->player()->rconpassword()) == 0)) {
con_print << "^B" << client->player()->name() << "^F rcon: " << message.substr(command.size() + 1) << std::endl;
@@ -754,46 +801,13 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
}
return;
- }
- // cup - client update entity
- if (command == "cup") {
- //con_debug << message << "\n";
- unsigned int id;
- if (msgstream >> id) {
- Entity *entity = Entity::find(id);
- if (!entity) {
- con_warn << client->host() << ":" << client->port() << " update for unknown entity " << id << "\n";
- return;
- }
-
- if (entity->type() != Entity::Controlable) {
- con_warn << client->host() << ":" << client->port() << " update for non-controlable entity " << id << "\n";
- return;
- }
-
- EntityControlable *entitycontrolable = (EntityControlable *)entity;
-
- if (entitycontrolable->owner() != client->player()) {
- con_warn << client->host() << ":" << client->port() << " update for non-owned entity " << id << "\n";
- return;
- }
-
- entitycontrolable->set_dirty(true);
- entitycontrolable->receive_client_update(msgstream);
- }
- return;
- }
-
- // say
- if (command == "say") {
+ } else if (command.compare("say") == 0 ) {
if (message.size() > command.size() + 1) {
server()->say(client->player(), message.substr(command.size() + 1));
}
return;
- }
- // priv
- if (command == "priv") {
+ } else if (command.compare("priv") == 0 ) {
if (message.size() > command.size() + 1) {
server()->private_message(client->player(), message.substr(command.size() + 1));
}