diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/input.cc | 6 | ||||
-rw-r--r-- | src/core/Makefile.am | 4 | ||||
-rw-r--r-- | src/core/gameserver.cc | 162 | ||||
-rw-r--r-- | src/core/gameserver.h | 14 | ||||
-rw-r--r-- | src/core/message.h | 2 | ||||
-rw-r--r-- | src/core/netclient.cc | 5 | ||||
-rw-r--r-- | src/core/netclient.h | 10 | ||||
-rw-r--r-- | src/core/netplayer.cc | 76 | ||||
-rw-r--r-- | src/core/netplayer.h | 40 | ||||
-rw-r--r-- | src/core/netserver.cc | 25 | ||||
-rw-r--r-- | src/core/netserver.h | 9 | ||||
-rw-r--r-- | src/core/player.cc | 17 | ||||
-rw-r--r-- | src/core/player.h | 11 | ||||
-rw-r--r-- | src/game/base/base.cc | 27 | ||||
-rw-r--r-- | src/game/base/ship.cc | 18 | ||||
-rw-r--r-- | src/game/example/example.cc | 2 |
16 files changed, 222 insertions, 206 deletions
diff --git a/src/client/input.cc b/src/client/input.cc index 026237e..9cb48a1 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -827,8 +827,10 @@ void frame() if ((render::Camera::mode() == render::Camera::Track) || (render::Camera::mode() == render::Camera::Cockpit)) { - local_direction = mouse_direction * math::absf(mouse_direction); - local_pitch = mouse_pitch * math::absf(mouse_pitch); + //local_direction = mouse_direction * math::absf(mouse_direction); + //local_pitch = mouse_pitch * math::absf(mouse_pitch); + local_direction = mouse_direction; + local_pitch = mouse_pitch; } else if (render::Camera::mode() == render::Camera::Free) { // squared values to smoothen camera movement diff --git a/src/core/Makefile.am b/src/core/Makefile.am index edd62e1..61622e0 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -3,8 +3,8 @@ INCLUDES = -I$(top_srcdir)/src libcore_la_SOURCES = application.cc clientstate.cc commandbuffer.cc core.cc \ cvar.cc entity.cc func.cc gameconnection.cc gameinterface.cc gameserver.cc \ - module.cc netclient.cc netconnection.cc netserver.cc parser.cc player.cc stats.cc \ - timer.cc zone.cc + module.cc netclient.cc netconnection.cc netplayer.cc netserver.cc parser.cc \ + player.cc stats.cc timer.cc zone.cc libcore_la_LDFLAGS = -avoid-version -no-undefined libcore_la_LIBADD = $(top_builddir)/src/model/libmodel.la \ $(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/math/libmath.la $(top_builddir)/src/sys/libsys.la \ diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 3268e38..db99356 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -62,7 +62,7 @@ void func_mute(std::string const &args) targetplayer->player_mute = true; server()->broadcast("^B" + targetplayer->name() + "^B has been muted.", targetplayer); - server()->send(targetplayer, "^BYou have been muted."); + targetplayer->send("^BYou have been muted."); } void func_unmute(std::string const &args) @@ -78,7 +78,7 @@ void func_unmute(std::string const &args) targetplayer->player_mute = false; server()->broadcast("^B" +targetplayer->name() + "^B has been unmuted.", targetplayer); - server()->send(targetplayer, "^BYou have been unmuted."); + targetplayer->send("^BYou have been unmuted."); } void func_kick(std::string const &args) @@ -271,7 +271,7 @@ void GameServer::say(Player *player, std::string const &message) return; if (player->mute()) { - send(player, "^BYou have been muted."); + player->send("^BYou have been muted."); return; } @@ -280,7 +280,7 @@ void GameServer::say(Player *player, std::string const &message) notification.append("^F:^N "); notification.append(message); - broadcast_message(Message::Public, notification); + broadcast(Message::Public, notification); } void GameServer::private_message(Player *player, std::string const &args) @@ -289,7 +289,7 @@ void GameServer::private_message(Player *player, std::string const &args) return; if (player->mute()) { - send(player, "^BYou have been muted."); + player->send("^BYou have been muted."); return; } @@ -301,14 +301,14 @@ void GameServer::private_message(Player *player, std::string const &args) core::Player *targetplayer = core::server()->find_player(target); if (!targetplayer) { - send(player, "^BPlayer " + target + "^B not found."); + player->send("^BPlayer " + target + "^B not found."); return; } std::string message(args.substr(target.size())); - send_message(Message::Private, player, "^FTo ^B" + targetplayer->name() + "^F:" + message); - send_message(Message::Private, targetplayer, "^FFrom ^B" + player->name() + "^F:" + message); + player->message(Message::Private, "^FTo ^B" + targetplayer->name() + "^F:" + message); + targetplayer->message(Message::Private, "^FFrom ^B" + player->name() + "^F:" + message); } // FIXME kicked by @@ -322,7 +322,7 @@ void GameServer::kick(Player *player, std::string const &reason) NetClient *client = server_network->find_client(player); if (client) { broadcast("^B" + player->name() + "^B has been kicked: " + reason, player); - server_network->send_message(client, "info", "^WYou have been kicked: " + reason); + player->send("^WYou have been kicked: " + reason); server_network->send_disconnect(client); } else { con_print << "Network client not found." << std::endl; @@ -330,146 +330,38 @@ 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) +void GameServer::broadcast(const std::string text, Player *ignore_player) { - if (!message.size()) - return; - - broadcast_message(Message::Info, message, ignore_player); -} - -// send and "info" message to a single player -void GameServer::send(Player *player, std::string const message) -{ - send_message(Message::Info, player, message); + broadcast(Message::Info, text, ignore_player); } -// send an rcon message to a single player -void GameServer::send_rcon(Player *player, std::string const message) -{ - send_message(Message::RCon, player, message); -} - -void GameServer::send_message(Message::Channel const channel, Player *player, std::string const message) -{ - if (!message.size()) - return; - - if (player == localplayer()) { - application()->notify_message(channel, message); - return; - } else { - if (server_network) { - std::string msg_channel; - switch(channel) { - case core::Message::Info: // Info message - msg_channel.assign("info"); - break; - - case core::Message::Local: // Chat message in the local zone - msg_channel.assign("local"); - break; - - case core::Message::Public: // Public chat message - msg_channel.assign("public"); - break; - - case core::Message::Private: // Private chat message - msg_channel.assign("private"); - break; - - case core::Message::RCon: // RCon message - msg_channel.assign("rcon"); - break; - - default: - con_warn << "message on unknown channel " << channel << "!" << std::endl; - return; - break; - } - - NetClient *client = server_network->find_client(player); - if (client) { - server_network->send_message(client, msg_channel.c_str(), message); - } - } - } -} // broadcast a message on a specified channel to all players -void GameServer::broadcast_message(Message::Channel const channel, std::string const message, Player *ignore_player) +void GameServer::broadcast(const Message::Channel channel, const std::string text, Player *ignore_player) { - if (!message.size()) + if (!text.size()) return; - // send to application - if (ignore_player != game()->localplayer()) - application()->notify_message(channel, message); - - // broadcast to remote clients - if (server_network) { - std::string msg_channel; - switch(channel) { - case core::Message::Info: // Info message - msg_channel.assign("info"); - break; - - case core::Message::Local: // Chat message in the local zone - msg_channel.assign("local"); - break; - - case core::Message::RCon: // RCon message - msg_channel.assign("rcon"); - break; - - case core::Message::Public: // Public chat message - msg_channel.assign("public"); - break; - - default: - con_warn << "message on unknown channel " << channel << "!" << std::endl; - return; - break; + for (Players::iterator it = players().begin(); it != players().end(); it++) { + Player *player = (*it); + if (player != ignore_player) { + Player *player = (*it); + player->message(channel, text); } - - server_network->broadcast_message(msg_channel.c_str(), message); } } // broadcast a sound event to all players -void GameServer::broadcast_sound(std::string const sound, Player *ignore_player) +void GameServer::broadcast_sound(const std::string name, Player *ignore_player) { - if (!sound.size()) + if (!name.size()) return; - // send to application - if (ignore_player != game()->localplayer()) { - application()->notify_sound(sound.c_str()); - } - - // broadcast to remote clients - if (server_network) { - server_network->broadcast_message("snd", sound, ignore_player); - } -} - -// send a sound event to a single player -void GameServer::send_sound(Player *player, std::string const sound) -{ - if (!sound.size()) - return; - - // send to application - if (player == localplayer()) { - application()->notify_sound(sound.c_str()); - return; - } - - // send to remote client - if (server_network) { - NetClient *client = server_network->find_client(player); - if (client) { - server_network->send_message(client, "snd", sound); + for (Players::iterator it = players().begin(); it != players().end(); it++) { + Player *player = (*it); + if (player != ignore_player) { + Player *player = (*it); + player->sound(name); } } } @@ -507,7 +399,7 @@ void GameServer::exec(Player *player, std::string const & cmdline) function->exec(args); while(console()->rconbuf().size()) { - send(player, (*console()->rconbuf().begin())); + player->message(Message::RCon, (*console()->rconbuf().begin())); console()->rconbuf().pop_front(); } @@ -520,7 +412,7 @@ void GameServer::exec(Player *player, std::string const & cmdline) std::string message("Unknown command '"); message.append(command); message.append("^N'"); - send(player, message); + player->send(message); } void GameServer::player_connect(Player *player) diff --git a/src/core/gameserver.h b/src/core/gameserver.h index 4ea476b..8d9ca9b 100644 --- a/src/core/gameserver.h +++ b/src/core/gameserver.h @@ -63,23 +63,11 @@ public: void broadcast(std::string const message, Player *ignore_player = 0); /// broadcast a message to all players on a specified channel - void broadcast_message(Message::Channel const channel, std::string const message, Player *ignore_player = 0); - - /// send an Info message to a single player - void send(Player *player, std::string const message); - - /// send a RCon message to a single player - void send_rcon(Player *player, std::string const message); - - /// send a message on the specific channel to the specified Player - void send_message(Message::Channel const channel, Player *player, std::string const message); + void broadcast(Message::Channel const channel, 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 sound to a single player - void send_sound(Player *player, std::string const sound); - /// a player sends a command to the game server void exec(Player *player, std::string const &cmdline); diff --git a/src/core/message.h b/src/core/message.h index 53d24be..b9a9661 100644 --- a/src/core/message.h +++ b/src/core/message.h @@ -14,7 +14,7 @@ class Message { public: /// indicates the type of message - enum Channel {Info=0, Public=1, Local=2, Private=3, RCon=4 }; + enum Channel {Info=0, Public=1, Local=2, Private=3, RCon=4}; }; } diff --git a/src/core/netclient.cc b/src/core/netclient.cc index 1289319..f75d8f3 100644 --- a/src/core/netclient.cc +++ b/src/core/netclient.cc @@ -24,6 +24,8 @@ NetClient::NetClient(std::string host, int port) : client_error = true; client_state = Connecting; + client_player = new NetPlayer(this); + con_print << host << ":" << port << " connected." << std::endl; client_host = host; @@ -52,6 +54,7 @@ NetClient::NetClient(std::string host, int port) : NetClient::~NetClient() { con_print << host() << ":" << port() << " disconnected." << std::endl; + delete client_player; } void NetClient::abort() @@ -71,7 +74,7 @@ int NetClient::port() const Player *NetClient::player() { - return &client_player; + return client_player; } bool NetClient::has_messages() const { diff --git a/src/core/netclient.h b/src/core/netclient.h index 879a801..6e5bcf9 100644 --- a/src/core/netclient.h +++ b/src/core/netclient.h @@ -29,7 +29,12 @@ #include <deque> #include <map> -#include "core/player.h" +namespace core +{ +class NetClient; +} + +#include "core/netplayer.h" namespace core { @@ -82,8 +87,9 @@ private: struct sockaddr_in client_addr; std::string client_host; int client_port; - Player client_player; bool client_error; + + NetPlayer *client_player; std::string messageblock; std::deque<std::string> recvq; diff --git a/src/core/netplayer.cc b/src/core/netplayer.cc new file mode 100644 index 0000000..24a597f --- /dev/null +++ b/src/core/netplayer.cc @@ -0,0 +1,76 @@ +/* + net/netplayer.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include <string> + +#include "core/netplayer.h" +#include "sys/sys.h" + +namespace core +{ + +NetPlayer::NetPlayer(NetClient *client) : Player() +{ + + player_client = client; +} + +NetPlayer::~NetPlayer() +{ +} + +void NetPlayer::sound(const std::string name) +{ + std::string msg("msg snd "); + msg.append(name); + msg += '\n'; + + player_client->send_raw(msg); +} + +void NetPlayer::message(Message::Channel channel, const std::string text) +{ + if (!text.size()) + return; + + std::string msg_channel; + switch(channel) { + case core::Message::Info: // Info message + msg_channel.assign("info"); + break; + + case core::Message::Local: // Chat message in the local zone + msg_channel.assign("local"); + break; + + case core::Message::Public: // Public chat message + msg_channel.assign("public"); + break; + + case core::Message::Private: // Private chat message + msg_channel.assign("private"); + break; + + case core::Message::RCon: // RCon message + msg_channel.assign("rcon"); + break; + + default: + con_warn << "message on unknown channel " << channel << "!" << std::endl; + return; + break; + } + + std::string msg("msg "); + msg.append(msg_channel); + msg += ' '; + msg.append(text); + msg += '\n'; + + player_client->send_raw(msg); +} + +} diff --git a/src/core/netplayer.h b/src/core/netplayer.h new file mode 100644 index 0000000..bbabea6 --- /dev/null +++ b/src/core/netplayer.h @@ -0,0 +1,40 @@ +/* + core/netplayer.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CORE_NETPLAYER_H__ +#define __INCLUDED_CORE_NETPLAYER_H__ + +namespace core +{ +class NetPlayer; +} + +#include "core/player.h" +#include "core/netclient.h" +#include "core/message.h" + +namespace core +{ + +class NetPlayer : public Player +{ +public: + NetPlayer(NetClient *client); + virtual ~NetPlayer(); + + NetClient *client() { return player_client; } + + virtual void message(Message::Channel const channel, const std::string text); + virtual void sound(const std::string name); + +private: + NetClient *player_client; +}; + +} + +#endif // __INCLUDED_CORE_NETCLIENT_H__ + diff --git a/src/core/netserver.cc b/src/core/netserver.cc index c6214c9..3f0d2e8 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -282,7 +282,7 @@ void NetServer::client_initialize(NetClient *client) { // send welcome message std::string welcome("^B"); welcome.append(Cvar::sv_name->str()); - send_message(client, "info", welcome); + client->player()->send(welcome); client->transmit(fd()); // send zones @@ -406,25 +406,6 @@ void NetServer::frame(unsigned long timestamp) * zone <id> <zone create/update data> */ -// broadcast a "msg <channel>" message to all clients -void NetServer::broadcast_message(const char *channel, std::string const & message, Player *ignore_player) -{ - if (!channel) - return; - - std::string msg("msg "); - msg.append(channel); - msg += ' '; - msg.append(message); - msg += '\n'; - - for (Clients::iterator it = clients.begin(); it != clients.end(); it++) { - if (((*it)->player() && (*it)->player() != ignore_player) && ((*it)->state() == NetClient::Connected)) { - (*it)->send_raw(msg); - } - } -} - // send a "msg <channel>" message to one client void NetServer::send_message(NetClient *client, const char *channel, std::string const & message) { @@ -625,7 +606,7 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me core::CommandBuffer::exec(); while(console()->rconbuf().size()) { - server()->send(client->player(), (*console()->rconbuf().begin())); + send_message(client, "rcon", (*console()->rconbuf().begin())); core::console()->rconbuf().pop_front(); } @@ -633,7 +614,7 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me console()->set_rcon(false); } else { - server()->send(client->player(), "rcon access denied"); + send_message(client, "info", "rcon access denied"); con_print << "^B" << client->player()->name() << "^W rcon access denied" << std::endl; } } diff --git a/src/core/netserver.h b/src/core/netserver.h index 8877707..647368e 100644 --- a/src/core/netserver.h +++ b/src/core/netserver.h @@ -58,12 +58,6 @@ public: /// receive data from clients void receive(); - /// broadcast a message - void broadcast_message(const char *channel, std::string const & message, Player *ignore_player=0); - - /// send a message to a client - void send_message(NetClient *client, const char *channel, std::string const & message); - /// disconnect a client void send_disconnect(NetClient *client); @@ -71,6 +65,9 @@ public: NetClient *find_client(Player const *player); protected: + /// send a message + void send_message(NetClient *client, const char *channel, std::string const & message); + /// send a server frame marker void send_frame_marker(NetClient *client, unsigned long timestamp); diff --git a/src/core/player.cc b/src/core/player.cc index 865c859..ca985ab 100644 --- a/src/core/player.cc +++ b/src/core/player.cc @@ -10,6 +10,7 @@ #include "sys/sys.h" #include "core/player.h" #include "core/cvar.h" +#include "core/application.h" namespace core { @@ -40,6 +41,22 @@ void Player::clear() player_control = 0; } + +void Player::send(const std::string text) +{ + message(core::Message::Info, text); +} + +void Player::sound(const std::string name) +{ + application()->notify_sound(name.c_str()); +} + +void Player::message(Message::Channel channel, const std::string text) +{ + application()->notify_message(channel, text); +} + void Player::set_control(EntityControlable *entitycontrolable) { player_control = entitycontrolable; diff --git a/src/core/player.h b/src/core/player.h index 04f9615..620f086 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -13,6 +13,7 @@ class Player; } #include "core/entity.h" +#include "core/message.h" #include "core/zone.h" #include "math/mathlib.h" @@ -29,7 +30,7 @@ public: /// default constructor Player(); /// default destructor - ~Player(); + virtual ~Player(); /*----- inspectors ------------------------------------------------ */ @@ -75,6 +76,14 @@ public: /// view inline Entity *view() { return player_view; } +/*----- messages -------------------------------------------------- */ + + void send(const std::string name); + + virtual void sound(const std::string name); + + virtual void message(core::Message::Channel channel, const std::string text); + /*----- mutators -------------------------------------------------- */ /// serialize player info to a stream diff --git a/src/game/base/base.cc b/src/game/base/base.cc index dfde132..7fa5299 100644 --- a/src/game/base/base.cc +++ b/src/game/base/base.cc @@ -59,7 +59,7 @@ void Base::func_join(core::Player *player, std::string const &args) ship->entity_location.assign(dock->location() + (dock->axis().forward() * dock->radius()*2.0f)); ship->entity_axis.assign(dock->axis()); */ - core::server()->send_sound(player, "game/buy-ship"); + player->sound("game/buy-ship"); std::string message("^B"); message.append(player->name()); @@ -128,34 +128,39 @@ void Base::func_buy(core::Player *player, std::string const &args) player->set_control(ship); core::server()->broadcast("^B" + player->name() + " ^Bpurchased " + aux::article(shipmodel->name())); - core::server()->send_sound(player, "game/buy-ship"); + player->sound("game/buy-ship"); } else { - core::server()->send(player, "Usage: buy [^B" + helpstr + "^N]"); + player->send("Usage: buy [^B" + helpstr + "^N]"); } } // a player sends standard hails void Base::func_hail(core::Player *player, std::string const &args) { + if (player->mute()) { + player->send("^BYou have been muted."); + return; + } + std::string target; std::istringstream is(args); if (!(is >> target)) { - core::server()->send(player, "Usage: hail [player]"); + player->send("Usage: hail [player]"); return; } core::Player *targetplayer = core::server()->find_player(target); if (!targetplayer) { - core::server()->send(player, "^BPlayer " + target + "^B not found."); + player->send("^BPlayer " + target + "^B not found."); return; } - core::server()->send(player, "^BYou hail " + targetplayer->name() + "^B."); - core::server()->send_sound(player, "com/hail"); + player->send("^BYou hail " + targetplayer->name() + "^B."); + player->sound("com/hail"); - core::server()->send(targetplayer, "^B" + player->name() + "^B hails you!"); - core::server()->send_sound(targetplayer, "com/hail"); + targetplayer->send("^B" + player->name() + "^B hails you!"); + targetplayer->send("com/hail"); } // a player actives the hyperspace jump drive on his ship @@ -196,14 +201,14 @@ void Base::func_dock(core::Player *player,core::Entity *entity) return; if (math::distance(entity->location(), player->control()->location()) > 2.0f * entity->radius()) { - core::server()->send(player, "^B" + entity->name() + " is out of range!"); + player->send("^B" + entity->name() + " is out of range!"); return; } player->control()->location().assign(entity->location()); player->control()->set_eventstate(core::Entity::Docked); player->set_view(entity); - core::server()->send(player, "^BDocking at " + entity->name() + "^B..."); + player->send("^BDocking at " + entity->name() + "^B..."); } // launch request diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index 20f37c8..c7a5eda 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -105,23 +105,23 @@ void Ship::jump(std::string const &args) helpstr.append(zone->label()); } - core::server()->send(owner(), "Usage: jump [^B" + helpstr + "^N]"); + owner()->send("Usage: jump [^B" + helpstr + "^N]"); return; } aux::to_lowercase(target); jumptargetzone = core::Zone::find_zone(target); if (!jumptargetzone) { - core::server()->send(owner(), "Unknown system '" + target + '\''); + owner()->send("Unknown system '" + target + '\''); return; } if (jumptargetzone == zone()) { - core::server()->send(owner(), "Already in the " + jumptargetzone->name() + '.'); + owner()->send("Already in the " + jumptargetzone->name() + '.'); return; } - core::server()->send(owner(), "Jumping to the " + jumptargetzone->name()); + owner()->send("Jumping to the " + jumptargetzone->name()); set_zone(jumptargetzone); if (owner()->control() == (EntityControlable*) this) owner()->set_zone(jumptargetzone); @@ -134,14 +134,14 @@ void Ship::jump(std::string const &args) } else { if (!jumpdrive() && !Base::g_devel->value()) { - core::server()->send(owner(), "This ship is not equiped with a hyperspace drive!"); + owner()->send("This ship is not equiped with a hyperspace drive!"); return; } else if (entity_eventstate == core::Entity::Jump) { return; } else if (entity_eventstate == core::Entity::JumpInitiate) { - core::server()->send(owner(), "Jump aborted, hyperspace drive deactivated."); + owner()->send("Jump aborted, hyperspace drive deactivated."); ship_jumpdrive_timer = 0; entity_timer = 0; entity_eventstate = core::Entity::Normal; @@ -183,14 +183,14 @@ JumpPoint * Ship::find_closest_jumppoint() if (jumppoint && jumppoint->target()) { if (Base::g_jumppointrange->value() < d) { - core::server()->send(owner(), "Jumppoint out of range!"); + owner()->send("Jumppoint out of range!"); return 0; } else { - core::server()->send(owner(), "Jumping to the " + jumppoint->target()->zone()->name()); + owner()->send("Jumping to the " + jumppoint->target()->zone()->name()); return jumppoint; } } else { - core::server()->send(owner(), "No jumppoints found!"); + owner()->send("No jumppoints found!"); return 0; } diff --git a/src/game/example/example.cc b/src/game/example/example.cc index 4eeea00..9c3d55a 100644 --- a/src/game/example/example.cc +++ b/src/game/example/example.cc @@ -96,7 +96,7 @@ void Example::player_connect(core::Player *player) player->set_dirty(); // send a message to the player - core::server()->send(player, "Welcome to " + name()); + player->send("Welcome to " + name()); // broadcast a message to all players core::server()->broadcast("^B" + player->name() + " ^Bentered."); |