Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-07-16 22:55:07 +0000
committerStijn Buys <ingar@osirion.org>2008-07-16 22:55:07 +0000
commiteb075660e7cb61b138c2da337115c59857f89e17 (patch)
tree0fe031a8f3562b22f61d0f95b740fe5f2326fd7b
parentfecc54ad8c5a108831c2bc268f9dd7e16b511b7e (diff)
network protocol cleanup, radar test (doesn't work)
-rw-r--r--osirion.kdevelop.pcsbin777319 -> 779161 bytes
-rw-r--r--osirion.kdevses18
-rw-r--r--src/auxiliary/functions.cc13
-rw-r--r--src/auxiliary/functions.h5
-rw-r--r--src/client/console.cc1
-rw-r--r--src/client/keyboard.cc4
-rw-r--r--src/client/radar.cc36
-rw-r--r--src/client/view.cc131
-rw-r--r--src/core/clientstate.cc5
-rw-r--r--src/core/clientstate.h5
-rw-r--r--src/core/gameconnection.cc32
-rw-r--r--src/core/gameinterface.cc4
-rw-r--r--src/core/gameserver.cc157
-rw-r--r--src/core/gameserver.h6
-rw-r--r--src/core/netclient.cc3
-rw-r--r--src/core/netconnection.cc90
-rw-r--r--src/core/netconnection.h21
-rw-r--r--src/core/netserver.cc145
-rw-r--r--src/core/netserver.h30
-rw-r--r--src/render/camera.cc26
-rw-r--r--src/render/camera.h5
-rw-r--r--src/render/draw.cc65
-rw-r--r--src/render/text.cc8
23 files changed, 551 insertions, 259 deletions
diff --git a/osirion.kdevelop.pcs b/osirion.kdevelop.pcs
index 9d49317..fd56608 100644
--- a/osirion.kdevelop.pcs
+++ b/osirion.kdevelop.pcs
Binary files differ
diff --git a/osirion.kdevses b/osirion.kdevses
index 650010c..c959ca4 100644
--- a/osirion.kdevses
+++ b/osirion.kdevses
@@ -1,19 +1,25 @@
<?xml version = '1.0' encoding = 'UTF-8'?>
<!DOCTYPE KDevPrjSession>
<KDevPrjSession>
- <DocsAndViews NumberOfDocuments="4" >
+ <DocsAndViews NumberOfDocuments="6" >
<Doc0 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/render/draw.cc" >
- <View0 Encoding="" line="786" Type="Source" />
+ <View0 Encoding="" Type="Source" />
</Doc0>
<Doc1 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/client/view.cc" >
- <View0 Encoding="" line="178" Type="Source" />
+ <View0 Encoding="" Type="Source" />
</Doc1>
- <Doc2 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/render/camera.cc" >
- <View0 Encoding="" line="267" Type="Source" />
+ <Doc2 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/client/radar.cc" >
+ <View0 Encoding="" Type="Source" />
</Doc2>
<Doc3 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/client/input.cc" >
- <View0 Encoding="" line="235" Type="Source" />
+ <View0 Encoding="" Type="Source" />
</Doc3>
+ <Doc4 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/client/keyboard.cc" >
+ <View0 Encoding="" line="147" Type="Source" />
+ </Doc4>
+ <Doc5 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/game/game.cc" >
+ <View0 Encoding="" line="81" Type="Source" />
+ </Doc5>
</DocsAndViews>
<pluginList>
<kdevdebugger>
diff --git a/src/auxiliary/functions.cc b/src/auxiliary/functions.cc
index 5edff56..dbfc799 100644
--- a/src/auxiliary/functions.cc
+++ b/src/auxiliary/functions.cc
@@ -96,7 +96,7 @@ const std::string text_strip_lowercase(const std::string &text)
return r;
}
-const std::string spaces(const std::string &text,size_t n)
+const std::string pad_left(const std::string &text,size_t n)
{
size_t l = text_length(text);
if (n <= l)
@@ -108,6 +108,17 @@ const std::string spaces(const std::string &text,size_t n)
return s;
}
+const std::string pad_right(const std::string &text,size_t n)
+{
+ size_t l = text_length(text);
+ if (n <= l)
+ return text;
+
+ std::string s(text);
+ s.append(n-l, ' ');
+ return s;
+}
+
void to_lowercase(std::string &text)
{
for (std::string::iterator i = text.begin(); i != text.end(); ++i)
diff --git a/src/auxiliary/functions.h b/src/auxiliary/functions.h
index e8704d4..557ab45 100644
--- a/src/auxiliary/functions.h
+++ b/src/auxiliary/functions.h
@@ -35,7 +35,10 @@ inline bool is_color_code(char const *c) { return (is_base_color_code(c) || is_c
size_t text_length(const std::string &text);
/// prepend spaces to a string up to the desired lenght, excluding color codes
-const std::string spaces(const std::string &text, size_t n);
+const std::string pad_left(const std::string &text, size_t n);
+
+/// append spaces to a string up to the desired lenght, excluding color codes
+const std::string pad_right(const std::string &text, size_t n);
/// convert a string to lowercase
void to_lowercase(std::string &text);
diff --git a/src/client/console.cc b/src/client/console.cc
index b52f8a0..7bb1aaf 100644
--- a/src/client/console.cc
+++ b/src/client/console.cc
@@ -69,6 +69,7 @@ void Console::clear()
}
void Console::draw() {
+ flush();
if (visible())
draw_console();
else
diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc
index 83d31e8..be2240a 100644
--- a/src/client/keyboard.cc
+++ b/src/client/keyboard.cc
@@ -315,7 +315,7 @@ void Keyboard::add_key(const char *name, const unsigned int keysym, const char a
void Keyboard::list_keys()
{
for (iterator it = begin(); it != end(); it++) {
- con_print << " " << aux::spaces((*it).second->name(), 6) << " " << (*it).second->bind() << std::endl;
+ con_print << " " << aux::pad_left((*it).second->name(), 6) << " " << (*it).second->bind() << std::endl;
}
con_print << keys.size() << " keys" << std::endl;
}
@@ -325,7 +325,7 @@ void Keyboard::list_binds()
size_t n =0;
for (iterator it = begin(); it != end(); it++) {
if ((*it).second->bind().size()) {
- con_print << " " << aux::spaces((*it).second->name(), 6) << " " << (*it).second->bind() << std::endl;
+ con_print << " " << aux::pad_left((*it).second->name(), 6) << " " << (*it).second->bind() << std::endl;
n++;
}
}
diff --git a/src/client/radar.cc b/src/client/radar.cc
index cc4257e..cdf5391 100644
--- a/src/client/radar.cc
+++ b/src/client/radar.cc
@@ -4,14 +4,48 @@
the terms of the GNU General Public License version 2
*/
+#include "auxiliary/functions.h"
#include "core/core.h"
#include "client/radar.h"
#include "client/video.h"
#include "render/draw.h"
#include "render/render.h"
+#include "render/text.h"
+
namespace client
{
+void Radar::draw() {
+ using namespace render;
+
+ if (!core::localcontrol())
+ return;
+
+ float y = 4 + Text::fontheight();
+ Text::draw(4, y, "^N------------ ^BRadar test ^N--------------");
+ y += Text::fontheight();
+
+ gl::color(1.0f, 1.0f, 1.0f, 1.0f);
+
+ std::map<unsigned int, core::Entity *>::iterator it;
+ for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
+ core::Entity *entity = (*it).second;
+ core::ClientState *state = entity->state();
+
+ if (state && state->targetable() && entity->label().size()) {
+ gl::color(entity->color());
+ std::ostringstream line;
+ line << aux::pad_right(entity->name(), 24) <<
+ state->state_screenlocation[0] << " " <<
+ state->state_screenlocation[1] << " " <<
+ state->state_screenlocation[2] << " ";
+ Text::draw(4, y, line.str());
+ y += Text::fontheight();
+ }
+ }
+
+}
+/*
void Radar::draw()
{
using namespace render;
@@ -75,5 +109,5 @@ void Radar::draw()
glDisableClientState(GL_NORMAL_ARRAY);
//glDisableClientState(GL_COLOR_ARRAY);
}
-
+*/
}
diff --git a/src/client/view.cc b/src/client/view.cc
index 2bbae15..63718e1 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -63,69 +63,12 @@ void shutdown()
{
}
-void reset()
-{
- using namespace render;
-
- // set clear color
- gl::clearcolor(0.0f, 0.0f, 0.0f, 1.0f);
-
- // shading model: Gouraud (smooth, the default)
- gl::shademodel(GL_SMOOTH);
- //gl::shademodel(GL_FLAT);
-
- // load identity matrices
- gl::matrixmode(GL_MODELVIEW);
- gl::loadidentity();
-
- gl::matrixmode(GL_MODELVIEW);
- gl::loadidentity();
-
- // lighting
- GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 };
- GLfloat ambient_light[] = { 0.01f, 0.01f, 0.01f, 1.0f };
- GLfloat diffuse_light[] = { 0.2f, 0.2f, 0.2f, 1.0f };
- GLfloat specular_light[] = { 0.2f, 0.2f, 0.2f, 1.0f };
-
- glLightfv(GL_LIGHT0, GL_POSITION, light_position);
- glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light);
- glLightfv(GL_LIGHT0, GL_SPECULAR, specular_light);
-
- // color tracking
- glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
-
- GLfloat specular_reflectance[] = { 0.2f, 0.2f, 0.2f, 1.0f };
- glMaterialfv(GL_FRONT, GL_SPECULAR, specular_reflectance);
- glMateriali(GL_FRONT, GL_SHININESS, 128); // shininess 1-128
-
- gl::disable(GL_LIGHTING);
- gl::enable(GL_LIGHT0);
- gl::disable(GL_COLOR_MATERIAL);
-
- // culling
- gl::cullface(GL_BACK);
- gl::frontface(GL_CCW);
- gl::disable(GL_CULL_FACE);
-
- // depth
- gl::depthmask(GL_TRUE);
- gl::disable(GL_DEPTH_TEST);
-
- // alpha-blending
- gl::blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- gl::enable(GL_BLEND);
-
- // client state
-}
-
void draw_loader()
{
using namespace render;
render::Textures::bind("bitmaps/loader");
- gl::color(1.0f, 1.0f, 1.0f, 1.0f);
-
+
gl::begin(gl::Quads);
glTexCoord2f(0.0f, 0.0f);
@@ -139,6 +82,7 @@ void draw_loader()
glTexCoord2f(0.0f, 1.0f);
gl::vertex(0,video::height,0);
+
gl::end();
}
@@ -282,6 +226,62 @@ void draw_cursor()
gl::end();
}
+void reset()
+{
+ using namespace render;
+
+ // set clear color
+ gl::clearcolor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ // load identity matrices
+ gl::matrixmode(GL_MODELVIEW);
+ gl::loadidentity();
+
+ gl::matrixmode(GL_MODELVIEW);
+ gl::loadidentity();
+
+ // shading model: Gouraud (smooth, the default)
+ gl::shademodel(GL_SMOOTH);
+ //gl::shademodel(GL_FLAT);
+
+ // lighting settings for the default light GL_LIGHT0
+ GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 };
+ GLfloat ambient_light[] = { 0.01f, 0.01f, 0.01f, 1.0f };
+ GLfloat diffuse_light[] = { 0.2f, 0.2f, 0.2f, 1.0f };
+ GLfloat specular_light[] = { 0.2f, 0.2f, 0.2f, 1.0f };
+
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+ glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, specular_light);
+
+ // GL_LIGHT0 is always enabled
+ gl::enable(GL_LIGHT0);
+
+ // color tracking
+ glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
+
+ // material settings
+ GLfloat specular_reflectance[] = { 0.2f, 0.2f, 0.2f, 1.0f };
+ glMaterialfv(GL_FRONT, GL_SPECULAR, specular_reflectance);
+ glMateriali(GL_FRONT, GL_SHININESS, 128); // shininess 1-128
+
+ // alpha blending function
+ gl::blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ gl::disable(GL_LIGHTING);
+ gl::disable(GL_COLOR_MATERIAL);
+
+ gl::cullface(GL_BACK);
+ gl::frontface(GL_CCW);
+ gl::disable(GL_CULL_FACE);
+ gl::disable(GL_DEPTH_TEST);
+ gl::disable(GL_BLEND);
+
+ gl::disable(GL_TEXTURE_2D);
+
+}
+
void frame(float seconds)
{
using namespace render;
@@ -300,21 +300,20 @@ void frame(float seconds)
if (core::application()->connected() && core::game()->serverframetime()) {
render::draw(seconds); // draw the world
- if (draw_radar->value()) {
- Radar::draw();
- }
}
// switch to ortographic projection to draw the GUI
gl::matrixmode(GL_PROJECTION);
gl::loadidentity();
- glOrtho(0, video::width, video::height, 0, -1000.0f, 1000.0f);
+ glOrtho(0, video::width, video::height, 0, -1024.0f, 1024.0f);
gl::matrixmode(GL_MODELVIEW);
gl::loadidentity();
gl::enable(GL_TEXTURE_2D);
+ gl::color(1.0f, 1.0f, 1.0f, 1.0f);
+
if (!core::application()->connected()) {
// draw the loader bitmap
draw_loader();
@@ -322,9 +321,15 @@ void frame(float seconds)
// draw text elements
if (draw_ui->value()) {
+
Text::setfont("bitmaps/fonts/gui", 16, 24);
+
draw_status();
+ if (draw_radar->value()) {
+ Radar::draw();
+ }
+
// draw the mouse cursor
draw_cursor();
}
@@ -334,6 +339,8 @@ void frame(float seconds)
console()->draw();
gl::disable(GL_TEXTURE_2D);
+
+ gl::disable(GL_BLEND);
}
} //namespace view
diff --git a/src/core/clientstate.cc b/src/core/clientstate.cc
index b34b16a..cc9c79e 100644
--- a/src/core/clientstate.cc
+++ b/src/core/clientstate.cc
@@ -12,6 +12,11 @@ ClientState::ClientState()
{
state_visible = false;
state_detailvisible = false;
+ state_targetable = false;
+
+ for (size_t i = 0; i < 3; i++)
+ state_screenlocation[i] = 0;
+
state_fuzz = math::randomf();
}
diff --git a/src/core/clientstate.h b/src/core/clientstate.h
index 915f96f..6cd283d 100644
--- a/src/core/clientstate.h
+++ b/src/core/clientstate.h
@@ -41,6 +41,8 @@ public:
inline bool detailvisible() const { return state_detailvisible; }
+ inline bool targetable() const { return state_targetable; }
+
/// client render fuzz factor
inline float fuzz() const { return state_fuzz; };
@@ -53,8 +55,11 @@ public:
math::Vector3f state_previouslocation;
math::Axis state_previousaxis;
+ double state_screenlocation[3];
+
bool state_visible;
bool state_detailvisible;
+ bool state_targetable;
float state_fuzz;
};
diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc
index daf47e1..2085adb 100644
--- a/src/core/gameconnection.cc
+++ b/src/core/gameconnection.cc
@@ -22,6 +22,7 @@ GameConnection::GameConnection(std::string const &connectionstr)
connection_instance = this;
connection_network = 0;
connection_running = false;
+ connection_frametime = 0;
unsigned int port = DEFAULTPORT;
std::string host(connectionstr);
@@ -48,12 +49,14 @@ GameConnection::GameConnection(std::string const &connectionstr)
}
// send connect request
- std::stringstream netmsgstream("");
- netmsgstream << "connect " << PROTOCOLVERSION << "\n";
- connection_network->send(netmsgstream.str());
+ connection_network->send_connect();
connection_network->transmit();
- connection_frametime = 0;
+ if (!connection_network->connected()) {
+ abort();
+ return;
+ }
+
connection_running = true;
}
@@ -77,10 +80,7 @@ void GameConnection::forward(std::string const &cmdline)
if (!connection_network->connected())
return;
- std::string netmessage("cmd ");
- netmessage.append(cmdline);
- netmessage += '\n';
- connection_network->send(netmessage);
+ connection_network->send_command(cmdline);
}
void GameConnection::say(std::string const &args)
@@ -88,10 +88,7 @@ void GameConnection::say(std::string const &args)
if (!connection_network->connected())
return;
- std::string netmessage("say ");
- netmessage.append(args);
- netmessage += '\n';
- connection_network->send(netmessage);
+ connection_network->send_say(args);
}
void GameConnection::frame(float seconds)
@@ -120,15 +117,10 @@ void GameConnection::frame(float seconds)
if (connection_network->state() == NetConnection::Connected) {
- if(localcontrol() && localcontrol()->dirty()) {
- std::ostringstream netmsg;
- netmsg << "cup " << localcontrol()->id() << " ";
- localcontrol()->serialize_client_update(netmsg);
- netmsg << "\n";
-
- connection_network->send(netmsg.str());
+ if(localcontrol() && localcontrol()->dirty()) {
+ connection_network->send_clientupdate(localcontrol());
localcontrol()->entity_dirty = false;
- //con_debug << netmsg.str();
+
}
if (localplayer()->dirty()) {
diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc
index 4aa59be..23b27bc 100644
--- a/src/core/gameinterface.cc
+++ b/src/core/gameinterface.cc
@@ -130,8 +130,7 @@ void GameInterface::update_entity_clientstate(Entity *entity)
if(Cvar::cl_prediction->value() == 0) {
- entity->state()->state_axis.assign(entity->axis());
- entity->state()->state_location.assign(entity->location());
+ entity->state()->assign(entity);
return;
}
@@ -227,7 +226,6 @@ void GameInterface::update_entity_clientstate(Entity *entity)
}
} else {
-
entity->state()->assign(entity);
}
}
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index 0a2370c..1866ad3 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -155,14 +155,14 @@ GameServer::GameServer() : GameInterface()
func->set_info("[player] [reason] kick a player from the server");
/*
func = Func::add("grant_rcon", func_grant_rcon);
- func->set_info("[player] grant a player rcon rights");
+ func->set_info("[player] grant rcon rights");
func = Func::add("revoke_rcon", func_grant_rcon);
- func->set_info("[player] revoke a player's rcon rights");
+ func->set_info("[player] revoke rcon rights");
*/
/* -- player functions --*/
func = Func::add("time", func_time, Func::Shared);
- func->set_info("get the server uptime and current localtime");
+ func->set_info("get the server uptime and current server localtime");
func = Func::add("who", func_who, Func::Shared);
func->set_info("get a list of connected players");
@@ -224,7 +224,7 @@ void GameServer::list_players()
for (std::list<Player *>:: iterator it = players.begin(); it != players.end(); it++) {
msgstr.str("");
- con_print << setw(3) << (*it)->id() << aux::spaces((*it)->name(), 24) << std::endl;
+ con_print << setw(3) << (*it)->id() << aux::pad_left((*it)->name(), 24) << std::endl;
count++;
}
@@ -293,16 +293,13 @@ void GameServer::say(Player *player, std::string const &message)
// broadcast to remote clients
if (server_network) {
- std::string netmessage("msg public ");
- netmessage.append(notification);
- netmessage += '\n';
- server_network->broadcast(netmessage);
+ server_network->broadcast_message("public", notification);
}
}
+// FIXME kicked by
void GameServer::kick(Player *player, std::string const &reason)
{
- // FIXME kicked by
if (!server_network) {
con_print << "Not running a networked server." << std::endl;
return;
@@ -322,92 +319,100 @@ void GameServer::kick(Player *player, std::string const &reason)
}
}
+// broadcast an "info" message to all players
void GameServer::broadcast(std::string const & message, Player *ignore_player)
{
+ if (!message.size())
+ return;
+
// send to application
if (ignore_player != game()->localplayer())
application()->notify_message(message);
// broadcast to remote clients
if (server_network) {
- std::string netmessage("msg info ");
- netmessage.append(message);
- netmessage += '\n';
- server_network->broadcast(netmessage, ignore_player);
+ server_network->broadcast_message("info", message, ignore_player);
}
}
-void GameServer::broadcast_sound(std::string const & sound, Player *ignore_player)
+// send and "info" message to a single player
+void GameServer::send(Player *player, std::string message)
{
+ if (!message.size())
+ return;
+
// send to application
- if (ignore_player != game()->localplayer())
- application()->notify_sound(sound.c_str());
+ if (player == localplayer()) {
+ application()->notify_message(message);
+ return;
+ }
- // broadcast to remote clients
+ // send to remote clients
if (server_network) {
- std::string netmessage("msg snd ");
- netmessage.append(sound);
- netmessage += '\n';
- server_network->broadcast(netmessage, ignore_player);
+ NetClient *client = server_network->find_client(player);
+ if (client) {
+ server_network->send_message(client, "info", message);
+ }
}
}
-void GameServer::send(Player *player, std::string message)
+// broadcast a sound event to all players
+void GameServer::broadcast_sound(std::string const & sound, Player *ignore_player)
{
+ if (!sound.size())
+ return;
+
// send to application
- if (player->id() == localplayer()->id()) {
- application()->notify_message(message);
+ if (ignore_player != game()->localplayer()) {
+ application()->notify_sound(sound.c_str());
}
- // send to remote clients
+ // broadcast to remote clients
if (server_network) {
- NetClient *client = server_network->find_client(player);
- if (client) {
- std::string netmessage("msg info ");
- netmessage.append(message);
- netmessage += '\n';
- server_network->send(client, netmessage);
- }
+ server_network->broadcast_message("snd", sound, ignore_player);
}
}
-void GameServer::send_rcon(Player *player, std::string message)
+// send a sound event to a single player
+void GameServer::send_sound(Player *player, std::string sound)
{
+ if (!sound.size())
+ return;
+
// send to application
- if (player->id() == localplayer()->id()) {
- con_print << message << std::endl;
+ if (player == localplayer()) {
+ application()->notify_sound(sound.c_str());
+ return;
}
- // send to remote clients
+ // send to remote client
if (server_network) {
NetClient *client = server_network->find_client(player);
if (client) {
- std::string netmessage("msg rcon ");
- netmessage.append(message);
- netmessage += '\n';
- server_network->send(client, netmessage);
+ server_network->send_message(client, "snd", sound);
}
}
}
-void GameServer::send_sound(Player *player, std::string sound)
+// send an rcon message to a single player
+void GameServer::send_rcon(Player *player, std::string message)
{
- if (player->id() == localplayer()->id()) {
- application()->notify_sound(sound.c_str());
+ // send to application
+ if (player == localplayer()) {
+ con_print << message << std::endl;
+ return;
}
// send to remote clients
if (server_network) {
NetClient *client = server_network->find_client(player);
if (client) {
- std::string netmessage("msg snd ");
- netmessage.append(sound);
- netmessage += '\n';
- server_network->send(client, netmessage);
+ server_network->send_message(client, "rcon", message);
}
}
}
+// execute a command for a remote player
void GameServer::exec(Player *player, std::string const & cmdline)
{
std::string command;
@@ -415,8 +420,6 @@ void GameServer::exec(Player *player, std::string const & cmdline)
cmdstream.str(cmdline);
cmdstream >> command;
- //con_debug << "Executing " << player->name() << ": " << cmdline << "\n";
-
Func *function = Func::find(command);
if (function ) {
@@ -425,7 +428,6 @@ void GameServer::exec(Player *player, std::string const & cmdline)
args.assign(cmdline.substr(command.size()+1));
if ((function ->flags() & Func::Game) == Func::Game) {
- //con_debug << "About to execute " << function->name() << " " << args << "'\n";
function->exec(player, args);
return;
} else if ((function->flags() & Func::Shared) == Func::Shared) {
@@ -436,8 +438,8 @@ void GameServer::exec(Player *player, std::string const & cmdline)
char line[MAXCMDSIZE];
- while(console()->buffer().getline(line, MAXCMDSIZE-1)) {
- send_rcon(player, std::string(line));
+ while(console()->buffer().getline(line, MAXCMDSIZE-1)) {
+ send(player, std::string(line));
}
// disable rcon buffering
@@ -552,61 +554,44 @@ void GameServer::frame(float seconds)
// send updates
if (server_network) {
+ // FIXME prevent connecting clients from receiving update frames
+
// transmit buffered sends
server_network->transmit();
// start server frame
- std::ostringstream framehdr;
- framehdr.str("");
- framehdr << "frame " << server_time << " " << server_previoustime << "\n";
- server_network->broadcast(framehdr.str());
+ server_network->broadcast_frame(server_time, server_previoustime);
+ // send changes in the world
std::map<unsigned int, Entity *>::iterator it;
for (it=Entity::registry.begin(); it != Entity::registry.end(); it++) {
+
Entity *entity = (*it).second;
+
if (entity->entity_destroyed) {
+
if (!entity->entity_created) {
- std::ostringstream netmsg;
- netmsg.str("");
- netmsg << "die " << entity->id() << "\n";
- server_network->broadcast(netmsg.str());
+ server_network->broadcast_entity_delete(entity);
}
+
core::Entity::remove(entity->id());
+
} else if (entity->entity_created) {
- std::ostringstream netmsg;
- netmsg.str("");
- netmsg << "ent ";
- entity->serialize(netmsg);
- netmsg << "\n";
- server_network->broadcast(netmsg.str());
+
+ server_network->broadcast_entity_create(entity);
entity->entity_created = false;
} else if (entity->dirty()) {
- std::ostringstream netmsg;
- netmsg.str("");
- netmsg << "sup " << entity->id() << " ";
- entity->serialize_server_update(netmsg);
- netmsg << "\n";
- netmsg.flush();
- server_network->broadcast(netmsg.str());
+
+ server_network->broadcast_entity_update(entity);
}
+
entity->entity_dirty = false;
}
// update player info
- for (std::list<NetClient *>::iterator it = server_network->clients.begin(); it != server_network->clients.end(); it++) {
- NetClient *client = *it;
- if (client->player()->dirty() && (client->state() == NetClient::Connected)) {
- // send player data
- std::ostringstream netmsg;
- netmsg.str("");
- netmsg << "pif ";
- client->player()->serialize_server_update(netmsg);
- netmsg << "\n";
- client->send(netmsg.str());
- client->player()->player_dirty = false;
- }
- }
+ server_network->broadcast_player_update();
+
// transmit buffered sends
server_network->transmit();
diff --git a/src/core/gameserver.h b/src/core/gameserver.h
index 172fb94..daf1abb 100644
--- a/src/core/gameserver.h
+++ b/src/core/gameserver.h
@@ -58,12 +58,12 @@ public:
/// broadcast a message to all players
void broadcast(std::string const & message, Player *ignore_player = 0);
- /// broadcast a sound to all players
- void broadcast_sound(std::string const & sound, Player *ignore_player = 0);
-
/// send a message to a single player
void send(Player *player, std::string message);
+ /// broadcast a sound to all players
+ void broadcast_sound(std::string const & sound, Player *ignore_player = 0);
+
/// send a sound to a single player
void send_sound(Player *player, std::string sound);
diff --git a/src/core/netclient.cc b/src/core/netclient.cc
index 310a64c..6113f32 100644
--- a/src/core/netclient.cc
+++ b/src/core/netclient.cc
@@ -113,6 +113,9 @@ void NetClient::receive(char *data)
void NetClient::send(std::string const &msg)
{
+ if (error())
+ return;
+
sendq.append(msg);
}
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc
index bee0843..e415518 100644
--- a/src/core/netconnection.cc
+++ b/src/core/netconnection.cc
@@ -274,23 +274,7 @@ void NetConnection::frame(float seconds)
}
}
-void NetConnection::send(std::string const &msg)
-{
- sendq.append(msg);
-}
-
-void NetConnection::send_playerinfo()
-{
- localplayer()->update_info();
-
- std::ostringstream osstream;
- osstream << "pif ";
- localplayer()->serialize_client_update(osstream);
- osstream << '\n';
- send(osstream.str());
- localplayer()->player_dirty = false;
-}
-
+// transmit all queued messages
void NetConnection::transmit()
{
@@ -328,6 +312,73 @@ void NetConnection::transmit()
connection_keepalive = application()->time();
}
+// queue a mmessage to the server
+void NetConnection::send(std::string const &msg)
+{
+ sendq.append(msg);
+}
+
+// functions for outgoing messages
+/**
+ * the following outgoing messages can be send
+ *
+ * connect <protocol version>
+ * pif <player data>
+ * cup <id> <entity data>
+ * cmd <text>
+ * say <text>
+ */
+
+// send a "connect" message to the server
+void NetConnection::send_connect()
+{
+ std::ostringstream msg;
+ msg << "connect " << PROTOCOLVERSION << "\n";
+ this->send(msg.str());
+}
+
+// send a "pif" player info message to the server
+void NetConnection::send_playerinfo()
+{
+ localplayer()->update_info();
+
+ std::ostringstream msg;
+ msg << "pif ";
+ localplayer()->serialize_client_update(msg);
+ msg << '\n';
+ this->send(msg.str());
+ localplayer()->player_dirty = false;
+}
+
+// send a "cup" client update message to the server
+void NetConnection::send_clientupdate(Entity *entity)
+{
+ // cup <id> <entity data>
+ std::ostringstream msg;
+ msg << "cup " << entity->id() << " ";
+ entity->serialize_client_update(msg);
+ msg << '\n';
+ this->send(msg.str());
+}
+
+// send a "cmd" command line message to the server
+void NetConnection::send_command(std::string const &cmdline)
+{
+ std::string msg("cmd ");
+ msg.append(cmdline);
+ msg += '\n';
+ this->send(msg);
+}
+
+// send a "say" chat message message to the server
+void NetConnection::send_say(std::string const &text)
+{
+ std::string msg("say ");
+ msg.append(text);
+ msg += '\n';
+ this->send(msg);
+}
+
// parse incoming client messages
/**
* The following incoming messages are parsed;
@@ -442,9 +493,12 @@ void NetConnection::parse_incoming_message(const std::string & message)
//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
+ } else {
+ // FIXME check of the received update matches the actual entity
entity->recieve_server_update(msgstream);
+ }
}
}
diff --git a/src/core/netconnection.h b/src/core/netconnection.h
index a2e9f2f..4e8d9f9 100644
--- a/src/core/netconnection.h
+++ b/src/core/netconnection.h
@@ -28,6 +28,7 @@
#include <deque>
#include <map>
+#include "core/entity.h"
#include "core/net.h"
namespace core
@@ -49,13 +50,22 @@ public:
/// process pending incoming messages
void frame(float seconds);
- /// buffer outgoing data
- void send(std::string const &msg);
+ /// send a connect message to the remote server
+ void send_connect();
- /// sennd a player info message
+ /// send a player info message to the remote server
void send_playerinfo();
- /// send bufered outgoing data
+ /// send a client update message to the remote server
+ void send_clientupdate(Entity *entity);
+
+ /// send a chat message
+ void send_say(std::string const &text);
+
+ /// send a command line to the remote server
+ void send_command(std::string const &cmdline);
+
+ /// transmit messages in the outgoing queue to the remote server
void transmit();
void abort();
@@ -81,6 +91,9 @@ public:
State connection_state;
protected:
+ /// add a message to the queue
+ void send(std::string const &msg);
+
/// receive incoming data and store messages
void receive();
diff --git a/src/core/netserver.cc b/src/core/netserver.cc
index fe6e45b..ac24f33 100644
--- a/src/core/netserver.cc
+++ b/src/core/netserver.cc
@@ -310,34 +310,153 @@ void NetServer::client_initialize(NetClient *client) {
client->client_state = NetClient::Pending;
}
-void NetServer::send(NetClient * client, std::string const & message)
+// find the client corresponding to a player
+NetClient *NetServer::find_client(Player const *player)
{
- client->send(message);
+ for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ if ((*it)->player() == player) {
+ return (*it);
+ }
+ }
+ return 0;
}
-// send a message to all clients
-void NetServer::broadcast(std::string const & message, Player *ignore_player)
+// send outgoing messages to clients
+
+/**
+ * The followig messages can be send to a client
+ *
+ * frame <timestamp> <previous timestamp>
+ * ent <id> <entity create data>
+ * die <id> <entity data>
+ * sup <entity update data>
+
+ * msg <channel> <text>
+ * supported message channels are "info" "public" "rcon" and "snd"
+ * "snd" is a special channel to transmit sound events
+ */
+
+// broadcast a "msg <channel>" message to all clients
+void NetServer::broadcast_message(const char *channel, std::string const & message, Player *ignore_player)
{
- //std::cout << "NetServer: " << osstream.str();
+ if (!channel)
+ return;
+
+ std::string msg("msg ");
+ msg.append(channel);
+ msg += ' ';
+ msg.append(message);
+ msg += '\n';
+
for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
- NetClient *client = *it;
- if (!client->error() && (client->state() == NetClient::Connected) && client->player() != ignore_player)
- client->send(message);
+ if (((*it)->player() && (*it)->player() != ignore_player) && ((*it)->state() == NetClient::Connected)) {
+ (*it)->send(msg);
+ }
}
}
-// find the client corresponding to a player
-NetClient *NetServer::find_client(Player const *player)
+// send a "msg <channel>" message to one client
+void NetServer::send_message(NetClient *client, const char *channel, std::string const & message)
+{
+ if (!channel)
+ return;
+
+ std::string msg("msg ");
+ msg.append(channel);
+ msg += ' ';
+ msg.append(message);
+ msg += '\n';
+
+ client->send(msg);
+}
+
+// broadcast a "frame" message to all clients
+void NetServer::broadcast_frame(float timestamp, float previoustimestamp)
{
+ std::ostringstream msg("");
+ msg << "frame " << timestamp << " " << previoustimestamp << "\n";
+
for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
- if ((*it)->player() == player) {
- return (*it);
+ if ((*it)->state() == NetClient::Connected) {
+ (*it)->send(msg.str());
+ }
+ }
+}
+
+// broadcast a "die" delete entity message to all clients
+void NetServer::broadcast_entity_delete(Entity *entity)
+{
+ std::ostringstream msg("");
+ msg << "die " << entity->id() << '\n';
+
+ for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ if ((*it)->state() == NetClient::Connected) {
+ (*it)->send(msg.str());
+ }
+ }
+}
+
+// broadcast a "ent" create entity message to all clients
+void NetServer::broadcast_entity_create(Entity *entity)
+{
+ std::ostringstream msg;
+ msg << "ent ";
+ entity->serialize(msg);
+ msg << '\n';
+
+ for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ if ((*it)->state() == NetClient::Connected) {
+ (*it)->send(msg.str());
+ }
+ }
+}
+
+// broadcast a "sup" server update entity message to all clients
+void NetServer::broadcast_entity_update(Entity *entity)
+{
+ std::ostringstream msg;
+ msg << "sup " << entity->id() << " ";
+ entity->serialize_server_update(msg);
+ msg << '\n';
+
+ for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ if ((*it)->state() == NetClient::Connected) {
+ (*it)->send(msg.str());
+ }
+ }
+}
+
+// broadcast a "pif" update player information if necessary
+void NetServer::broadcast_player_update()
+{
+ for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ NetClient *client = *it;
+
+ if (client->player()->dirty()) {
+ // send player data
+ std::ostringstream msg;
+ msg << "pif ";
+ client->player()->serialize_server_update(msg);
+ msg << '\n';
+ client->send(msg.str());
+
+ client->player()->player_dirty = false;
}
}
- return 0;
+}
+
+// send a "pif" update player information to a single player
+void NetServer::send_player_update(NetClient *client)
+{
+ std::ostringstream msg;
+ msg << "pif ";
+ client->player()->serialize_server_update(msg);
+ msg << '\n';
+ client->send(msg.str());
}
// parse incoming client messages
+
/**
* The following incoming protocol messages are parsed;
*
diff --git a/src/core/netserver.h b/src/core/netserver.h
index a83229c..25bca5f 100644
--- a/src/core/netserver.h
+++ b/src/core/netserver.h
@@ -52,17 +52,33 @@ public:
/// transmit data to clients
void transmit();
- /// broadcast network data to all clients
- void broadcast(std::string const & message, Player *ignore_player=0);
+ /// broadcast a message
+ void broadcast_message(const char *channel, std::string const & message, Player *ignore_player=0);
- /// send network data to one client
- void send(NetClient * client, std::string const & message);
+ /// send a message to a single client
+ void send_message(NetClient *client, const char *channel, std::string const & message);
+
+ /// broadcast a server frame message
+ void broadcast_frame(float timestamp, float previoustimestamp);
+
+ /// broadcast a delete entity event
+ void broadcast_entity_delete(Entity *entity);
+
+ /// broadcast a create entity event
+ void broadcast_entity_create(Entity *entity);
+
+ /// broadcast a update entity event
+ void broadcast_entity_update(Entity *entity);
+
+ /// broadcast updated player information, if necessary
+ void broadcast_player_update();
+
+ /// send an update player information message to a single client
+ void send_player_update(NetClient *client);
/// find the client corresponding to a player
NetClient *find_client(Player const *player);
- std::list<NetClient *> clients;
-
protected:
/// set the error state
void abort();
@@ -88,6 +104,8 @@ private:
int fdmax;
char recbuf[FRAMESIZE];
+
+ std::list<NetClient *> clients;
};
}
diff --git a/src/render/camera.cc b/src/render/camera.cc
index 287e4ad..8fe84a7 100644
--- a/src/render/camera.cc
+++ b/src/render/camera.cc
@@ -150,9 +150,8 @@ void Camera::next_mode()
}
}
-void Camera::draw(float seconds)
+void Camera::frame(float seconds)
{
- math::Matrix4f matrix;
math::Axis target_axis;
float d = 0;
@@ -304,14 +303,28 @@ void Camera::draw(float seconds)
distance += frustum_front;
+ // calculate eye position
+ camera_eye = camera_target - (distance * camera_axis.forward());
+}
+
+void Camera::draw()
+{
+ // Change to the projection matrix and set our viewing volume large enough for the skysphere
+ gl::matrixmode(GL_PROJECTION);
+ gl::loadidentity();
+ gl::frustum(-frustum_size*Camera::aspect(), frustum_size*Camera::aspect(),
+ -frustum_size, frustum_size, frustum_front, 2048.0f);
+
+ gl::matrixmode(GL_MODELVIEW);
+ gl::loadidentity();
+
// map world coordinates to opengl coordinates
gl::rotate(90.0f, 0, 1.0, 0);
gl::rotate(-90.0f, 1.0f , 0, 0);
- // assign transformation matrix
- matrix.assign(camera_axis);
-
// apply the transpose of the axis transformation (the axis is orhtonormal)
+ math::Matrix4f matrix;
+ matrix.assign(camera_axis);
gl::multmatrix(matrix.transpose());
// match the camera with the current target
@@ -319,9 +332,6 @@ void Camera::draw(float seconds)
// apply camera offset
gl::translate(distance * camera_axis.forward());
-
- // calculate eye position
- camera_eye = camera_target - (distance * camera_axis.forward());
}
void Camera::set_direction(float direction)
diff --git a/src/render/camera.h b/src/render/camera.h
index 52d2e13..edc3496 100644
--- a/src/render/camera.h
+++ b/src/render/camera.h
@@ -46,8 +46,11 @@ public:
/// reset the current mode
static void reset();
+ /// progress the camera
+ static void frame(float elapsed);
+
/// draw the OpenGL camera transformation
- static void draw(float elapsed);
+ static void draw();
/// set target direction
static void set_direction(float direction);
diff --git a/src/render/draw.cc b/src/render/draw.cc
index c650169..18c3d73 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -12,6 +12,7 @@
#include "render/render.h"
#include "render/textures.h"
#include "render/draw.h"
+#include "render/gl.h"
namespace render
{
@@ -36,7 +37,7 @@ math::Vector3f v6(-1, 1, -1);
math::Vector3f v7(-1, -1, -1);
const float drawdistance = 128.0f;
-const float drawfxdistance = 32.0f;
+const float drawfxdistance = 64.0f;
float angle = 0;
@@ -299,6 +300,15 @@ void pass_prepare(float seconds)
// reset light state
gl::disable(GL_LIGHT1);
+ // get the current OpenGL transformation matrices
+ GLdouble gl_projection_matrix[16];
+ GLdouble gl_model_matrix[16];
+ GLint gl_viewport[4];
+
+ glGetDoublev(GL_PROJECTION, gl_projection_matrix);
+ glGetDoublev(GL_MODELVIEW, gl_model_matrix);
+ glGetIntegerv(GL_VIEWPORT, gl_viewport);
+
std::map<unsigned int, core::Entity *>::iterator it;
for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
@@ -353,8 +363,9 @@ void pass_prepare(float seconds)
entity->entity_clientstate = new core::ClientState(entity);
}
- entity->state()->state_visible = true;
+ entity->state()->state_visible = false;
entity->state()->state_detailvisible = false;
+ entity->state()->state_targetable = false;
// calculate visibility for entities with models
if (entity->model()) {
@@ -373,6 +384,8 @@ void pass_prepare(float seconds)
}
} else {
+ entity->state()->state_visible = true;
+
if (entity->type() == core::Entity::Globe) {
core::EntityGlobe *globe = (core::EntityGlobe *) entity;
@@ -408,6 +421,21 @@ void pass_prepare(float seconds)
}
}
}
+
+ // calculate screen position
+ if (entity->state()->visible()) {
+ GLdouble x = 0;
+ GLdouble y = 0;
+ GLdouble z = 0;
+
+ math::Vector3f const & pos = entity->state()->location();
+ if (gluProject((GLdouble) pos.x , (GLdouble)pos.y, (GLdouble)pos.z, gl_model_matrix, gl_projection_matrix, gl_viewport, &x, &y, &z) == GL_TRUE) {
+ entity->state()->state_screenlocation[0] = x;
+ entity->state()->state_screenlocation[1] = y;
+ entity->state()->state_screenlocation[2] = z;
+ entity->state()->state_targetable = true;
+ }
+ }
}
}
@@ -723,7 +751,7 @@ void draw_pass_sky()
gl::push();
gl::translate(Camera::eye());
- draw_sphere_inside(math::Color(), 8192);
+ draw_sphere_inside(math::Color(), 128);
gl::pop();
gl::disable(GL_TEXTURE_2D);
@@ -747,6 +775,7 @@ void draw_pass_spacegrid()
gl::normal(0, 0, 1.0f);
gl::begin(gl::Lines);
+
for (int i=-gridsize; i <= gridsize; i++) {
gl::color(0,0, 0, 0);
gl::vertex(i-dx, -gridsize-dy, z);
@@ -780,15 +809,8 @@ void draw(float seconds)
angle -= 360.0f;
}
- // Change to the projection matrix and set our viewing volume large enough for the skysphere
- gl::matrixmode(GL_PROJECTION);
- gl::loadidentity();
- gl::frustum(-frustum_size*Camera::aspect(), frustum_size*Camera::aspect(),
- -frustum_size, frustum_size, frustum_front, 8192.0f);
-
- gl::matrixmode(GL_MODELVIEW);
- gl::loadidentity();
- Camera::draw(seconds); // draw the current camera transformation
+ Camera::frame(seconds);
+ Camera::draw(); // draw the current camera transformation
// calculate client state
pass_prepare(seconds);
@@ -813,24 +835,27 @@ void draw(float seconds)
glEnableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
- gl::disable(GL_BLEND); // disbable alpha blending
- gl::disable(GL_RESCALE_NORMAL);
+ gl::enable(GL_DEPTH_TEST);
+ gl::depthmask(GL_FALSE); // disable depth buffer writing
draw_pass_sky(); // draw the skysphere
- gl::enable(GL_DEPTH_TEST); // enable depth buffer writing
+
+ gl::depthmask(GL_TRUE); // enable writing to the depth buffer
+
gl::enable(GL_CULL_FACE); // enable culling
gl::enable(GL_COLOR_MATERIAL); // enable color tracking
gl::enable(GL_LIGHTING);
gl::enable(GL_RESCALE_NORMAL); // rescale normals by the transformation matrix scale factor
-
+
draw_pass_default(); // draw entities without model
+
+ gl::disable(GL_RESCALE_NORMAL);
glEnableClientState(GL_COLOR_ARRAY);
- gl::disable(GL_RESCALE_NORMAL);
draw_pass_model_vertex(); // draw entities with model
-
+
glDisableClientState(GL_COLOR_ARRAY);
draw_pass_model_evertex(); // draw entities with model, vertices with entity color
@@ -855,8 +880,8 @@ void draw(float seconds)
gl::disable(GL_LIGHTING);
gl::disable(GL_COLOR_MATERIAL); // disable color tracking
gl::disable(GL_CULL_FACE); // disable culling
- gl::disable(GL_DEPTH_TEST); // disable depth buffer
-
+
+ gl::disable(GL_DEPTH_TEST); // disable depth buffer testing
// GL_BLEND must be enabled for the GUI
}
diff --git a/src/render/text.cc b/src/render/text.cc
index 7c1ae8e..f5c221f 100644
--- a/src/render/text.cc
+++ b/src/render/text.cc
@@ -98,16 +98,16 @@ void Text::draw(float x, float y, const char ascii)
gl::begin(gl::Quads);
glTexCoord2f(fcol, frow);
- gl::vertex(x,y,1);
+ gl::vertex(x,y, 0);
glTexCoord2f(fcol + 0.0625f, frow);
- gl::vertex(x+text_fontwidth,y,1);
+ gl::vertex(x+text_fontwidth,y, 0);
glTexCoord2f(fcol +0.0625f, frow + 0.0625f);
- gl::vertex(x+text_fontwidth,y+text_fontheight,1);
+ gl::vertex(x+text_fontwidth,y+text_fontheight, 0);
glTexCoord2f(fcol, frow+0.0625f);
- gl::vertex(x,y+text_fontheight,1);
+ gl::vertex(x,y+text_fontheight, 0);
gl::end();
}