Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Server: Added ShellUser and ShellUsers
ShellUser and the ShellUsers collection manage the state of all the
shell connections open to a server.
  • Loading branch information
skyjake committed Jan 27, 2013
1 parent 7308d95 commit 5969b35
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 14 deletions.
59 changes: 59 additions & 0 deletions doomsday/server/include/shelluser.h
@@ -0,0 +1,59 @@
/** @file shelluser.h Remote user of a shell connection.
* @ingroup server
*
* @authors Copyright © 2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#ifndef SERVER_SHELLUSER_H
#define SERVER_SHELLUSER_H

#include <de/Socket>
#include <de/shell/Link>

/**
* Remote user of a shell connection.
*
* Contains all the user-specific data pertinent to a remote connected shell
* user.
*
* This is a server-side class representing a remote user connected to the
* server through a shell link.
*
* @ingroup server
*/
class ShellUser : public de::shell::Link
{
Q_OBJECT

public:
/**
* Constructs a new shell user from a previously opened socket.
*
* @param socket Open socket. User takes ownership.
*/
ShellUser(de::Socket *socket);

virtual ~ShellUser();

protected slots:
void handleIncomingPackets();

private:
struct Instance;
Instance *d;
};

#endif // SERVER_SHELLUSER_H
57 changes: 57 additions & 0 deletions doomsday/server/include/shellusers.h
@@ -0,0 +1,57 @@
/** @file shellusers.h All remote shell users.
* @ingroup server
*
* @authors Copyright © 2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#ifndef SERVER_SHELLUSERS_H
#define SERVER_SHELLUSERS_H

#include <QObject>
#include <QSet>
#include "shelluser.h"

/**
* All remote shell users.
*/
class ShellUsers : public QObject
{
Q_OBJECT

public:
ShellUsers();

~ShellUsers();

/**
* Adds a new remote shell user to the set of connected users. Users are
* automatically removed from this collection and deleted when they are
* disconnected.
*
* @param user User. Ownership transferred.
*/
void add(ShellUser *user);

int count() const;

protected slots:
void userDisconnected();

private:
QSet<ShellUser *> _users;
};

#endif // SERVER_SHELLUSERS_H
33 changes: 19 additions & 14 deletions doomsday/server/server.pro
Expand Up @@ -29,6 +29,7 @@ include(../dep_curses.pri)
include(../dep_lzss.pri)
include(../dep_deng2.pri)
include(../dep_deng1.pri)
include(../dep_shell.pri)

# TODO: Get rid of this. The dedicated server should need no GL code.
win32: include(../dep_opengl.pri)
Expand Down Expand Up @@ -120,6 +121,14 @@ DENG_HEADERS += \
# Private headers.
DENG_HEADERS += \
include/server_dummies.h \
include/shelluser.h \
include/shellusers.h \
include/server/sv_def.h \
include/server/sv_frame.h \
include/server/sv_infine.h \
include/server/sv_missile.h \
include/server/sv_pool.h \
include/server/sv_sound.h \
$$SRC/include/audio/s_cache.h \
$$SRC/include/audio/s_environ.h \
$$SRC/include/audio/s_logic.h \
Expand Down Expand Up @@ -262,12 +271,6 @@ DENG_HEADERS += \
$$SRC/include/resource/wad.h \
$$SRC/include/resource/zip.h \
$$SRC/include/resourceclass.h \
include/server/sv_def.h \
include/server/sv_frame.h \
include/server/sv_infine.h \
include/server/sv_missile.h \
include/server/sv_pool.h \
include/server/sv_sound.h \
$$SRC/include/sys_console.h \
$$SRC/include/sys_system.h \
$$SRC/include/tab_anorms.h \
Expand Down Expand Up @@ -336,11 +339,17 @@ macx {
else:unix {
}

SOURCES += $$SRC/src/ui/displaymode_dummy.c

# Platform-independent sources.
SOURCES += \
src/server_dummies.cpp \
src/shelluser.cpp \
src/shellusers.cpp \
src/server/sv_frame.cpp \
src/server/sv_infine.cpp \
src/server/sv_main.cpp \
src/server/sv_missile.cpp \
src/server/sv_pool.cpp \
src/server/sv_sound.cpp \
$$SRC/src/api_uri.cpp \
$$SRC/src/audio/s_cache.cpp \
$$SRC/src/audio/s_environ.cpp \
Expand Down Expand Up @@ -460,12 +469,6 @@ SOURCES += \
$$SRC/src/resource/tga.cpp \
$$SRC/src/resource/wad.cpp \
$$SRC/src/resource/zip.cpp \
src/server/sv_frame.cpp \
src/server/sv_infine.cpp \
src/server/sv_main.cpp \
src/server/sv_missile.cpp \
src/server/sv_pool.cpp \
src/server/sv_sound.cpp \
$$SRC/src/sys_system.cpp \
$$SRC/src/tab_tables.c \
$$SRC/src/ui/b_command.cpp \
Expand All @@ -477,6 +480,7 @@ SOURCES += \
$$SRC/src/ui/canvaswindow.cpp \
$$SRC/src/ui/dd_input.cpp \
$$SRC/src/ui/displaymode.cpp \
$$SRC/src/ui/displaymode_dummy.c \
$$SRC/src/ui/fi_main.cpp \
$$SRC/src/ui/finaleinterpreter.cpp \
$$SRC/src/ui/keycode.cpp \
Expand Down Expand Up @@ -513,6 +517,7 @@ macx {
QMAKE_INFO_PLIST = ../build/mac/Info.plist

linkBinaryToBundledLibdeng2($$TARGET)
linkBinaryToBundledLibdengShell($$TARGET)
}

# Installation ---------------------------------------------------------------
Expand Down
99 changes: 99 additions & 0 deletions doomsday/server/src/shelluser.cpp
@@ -0,0 +1,99 @@
/** @file shelluser.cpp Remote user of a shell connection.
* @ingroup server
*
* @authors Copyright © 2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#include "shelluser.h"
#include <de/shell/Protocol>
#include <de/LogSink>
#include <de/Log>
#include <de/LogBuffer>

#include "con_main.h"

using namespace de;

struct ShellUser::Instance : public LogSink
{
ShellUser &self;

/// Log entries to be sent are collected here.
shell::LogEntryPacket logEntryPacket;

Instance(ShellUser &inst) : self(inst)
{
// We will send all log entries to a shell user.
LogBuffer::appBuffer().addSink(*this);
}

~Instance()
{
LogBuffer::appBuffer().removeSink(*this);
}

LogSink &operator << (LogEntry const &entry)
{
logEntryPacket.add(entry);
return *this;
}

LogSink &operator << (String const &)
{
return *this;
}

/**
* Sends the accumulated log entries over the link.
*/
void flush()
{
if(!logEntryPacket.isEmpty() && self.status() == shell::Link::Connected)
{
self << logEntryPacket;
logEntryPacket.clear();
}
}
};

ShellUser::ShellUser(Socket *socket) : shell::Link(socket), d(new Instance(*this))
{
connect(this, SIGNAL(packetsReady()), this, SLOT(handleIncomingPackets()));
}

ShellUser::~ShellUser()
{
delete d;
}

void ShellUser::handleIncomingPackets()
{
forever
{
QScopedPointer<Packet> packet(nextPacket());
if(packet.isNull()) break;

switch(protocol().recognize(packet.data()))
{
case shell::Protocol::Command:
Con_Execute(CMDS_CONSOLE, protocol().command(*packet).toUtf8().constData(), false, true);
break;

default:
break;
}
}
}
57 changes: 57 additions & 0 deletions doomsday/server/src/shellusers.cpp
@@ -0,0 +1,57 @@
/** @file shellusers.cpp All remote shell users.
* @ingroup server
*
* @authors Copyright © 2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#include "shellusers.h"

ShellUsers::ShellUsers()
{
}

ShellUsers::~ShellUsers()
{
foreach(ShellUser *user, _users)
{
delete user;
}
}

void ShellUsers::add(ShellUser *user)
{
LOG_INFO("New shell user from %s") << user->address();

_users.insert(user);
connect(user, SIGNAL(disconnected()), this, SLOT(userDisconnected()));
}

int ShellUsers::count() const
{
return _users.size();
}

void ShellUsers::userDisconnected()
{
DENG2_ASSERT(dynamic_cast<ShellUser *>(sender()) != 0);

ShellUser *user = static_cast<ShellUser *>(sender());
_users.remove(user);

LOG_INFO("Shell user from %s has disconnected") << user->address();

user->deleteLater();
}

0 comments on commit 5969b35

Please sign in to comment.