summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/account-server/account.cpp94
-rw-r--r--src/account-server/account.hpp49
-rw-r--r--src/account-server/characterdata.cpp11
-rw-r--r--src/account-server/characterdata.hpp22
-rw-r--r--src/chat-server/chatclient.hpp6
-rw-r--r--src/chat-server/chathandler.cpp2
-rw-r--r--src/chat-server/chathandler.hpp3
-rw-r--r--src/defines.h19
-rw-r--r--src/game-server/character.hpp9
-rw-r--r--src/game-server/command.cpp223
-rw-r--r--src/game-server/gamehandler.cpp9
-rw-r--r--src/serialize/characterdata.hpp2
13 files changed, 307 insertions, 143 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 7d19c95f..6bc88be8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -87,6 +87,7 @@ tmwserv_game_SOURCES = \
game-server/character.cpp \
game-server/collisiondetection.hpp \
game-server/collisiondetection.cpp \
+ game-server/command.cpp \
game-server/deathlistener.hpp \
game-server/gamehandler.hpp \
game-server/gamehandler.cpp \
diff --git a/src/account-server/account.cpp b/src/account-server/account.cpp
index 6ca75535..fb4e0572 100644
--- a/src/account-server/account.cpp
+++ b/src/account-server/account.cpp
@@ -34,11 +34,11 @@ Account::Account(const std::string& name,
const std::string& password,
const std::string& email,
int id)
- : mID(id),
- mName(name),
+ : mName(name),
mPassword(password),
mEmail(email),
mCharacters(),
+ mID(id),
mLevel(AL_NORMAL)
{
// NOOP
@@ -73,87 +73,6 @@ Account::~Account()
/**
- * Set the user name.
- */
-void
-Account::setName(const std::string& name)
-{
- mName = name;
-}
-
-
-/**
- * Get the user name.
- */
-const std::string&
-Account::getName(void) const
-{
- return mName;
-}
-
-
-/**
- * Set the user password.
- */
-void
-Account::setPassword(const std::string& password)
-{
- mPassword = password;
-}
-
-
-/**
- * Get the user password.
- */
-const std::string
-Account::getPassword(void) const
-{
- return mPassword;
-}
-
-
-/**
- * Set the user email address.
- */
-void
-Account::setEmail(const std::string& email)
-{
- // Email validity is checked by Accounthandler
- mEmail = email;
-}
-
-
-/**
- * Get the user email address.
- */
-const std::string&
-Account::getEmail(void) const
-{
- return mEmail;
-}
-
-
-/**
- * Set the account level.
- */
-void
-Account::setLevel(AccountLevel level)
-{
- mLevel = level;
-}
-
-
-/**
- * Get the account level.
- */
-AccountLevel
-Account::getLevel(void) const
-{
- return mLevel;
-}
-
-
-/**
* Set the characters.
*/
void
@@ -191,15 +110,6 @@ bool Account::delCharacter(std::string const &name)
/**
- * Get all the characters.
- */
-Characters &Account::getCharacters()
-{
- return mCharacters;
-}
-
-
-/**
* Get a character by name.
*/
CharacterPtr Account::getCharacter(const std::string& name)
diff --git a/src/account-server/account.hpp b/src/account-server/account.hpp
index 50129579..6b1cf8a2 100644
--- a/src/account-server/account.hpp
+++ b/src/account-server/account.hpp
@@ -25,7 +25,6 @@
#include <string>
-#include "defines.h"
#include "account-server/characterdata.hpp"
#include "utils/countedptr.h"
@@ -85,8 +84,8 @@ class Account
*
* @param name the user name.
*/
- void
- setName(const std::string& name);
+ void setName(std::string const &name)
+ { mName = name; }
/**
@@ -94,8 +93,8 @@ class Account
*
* @return the user name.
*/
- const std::string&
- getName() const;
+ std::string const &getName() const
+ { return mName; }
/**
@@ -103,8 +102,8 @@ class Account
*
* @param password the user password.
*/
- void
- setPassword(const std::string& password);
+ void setPassword(std::string const &password)
+ { mPassword = password; }
/**
@@ -112,8 +111,8 @@ class Account
*
* @return the user password.
*/
- const std::string
- getPassword(void) const;
+ std::string const &getPassword() const
+ { return mPassword; }
/**
@@ -121,8 +120,8 @@ class Account
*
* @param email the user email address.
*/
- void
- setEmail(const std::string& email);
+ void setEmail(std::string const &email)
+ { mEmail = email; }
/**
@@ -130,8 +129,8 @@ class Account
*
* @return the user email address.
*/
- const std::string&
- getEmail(void) const;
+ std::string const &getEmail() const
+ { return mEmail; }
/**
@@ -139,8 +138,8 @@ class Account
*
* @param level the new level.
*/
- void
- setLevel(AccountLevel level);
+ void setLevel(int level)
+ { mLevel = level; }
/**
@@ -148,8 +147,8 @@ class Account
*
* @return the account level.
*/
- AccountLevel
- getLevel() const;
+ int getLevel() const
+ { return mLevel; }
/**
@@ -183,8 +182,16 @@ class Account
*
* @return all the characters.
*/
- Characters&
- getCharacters();
+ Characters &getCharacters()
+ { return mCharacters; }
+
+ /**
+ * Get all the characters.
+ *
+ * @return all the characters.
+ */
+ Characters const &getCharacters() const
+ { return mCharacters; }
/**
* Get a character by name.
@@ -215,12 +222,12 @@ class Account
private:
- int mID; /**< unique id */
std::string mName; /**< user name */
std::string mPassword; /**< user password (encrypted) */
std::string mEmail; /**< user email address */
Characters mCharacters; /**< Character data */
- AccountLevel mLevel; /**< account level */
+ int mID; /**< unique id */
+ unsigned char mLevel; /**< account level */
};
diff --git a/src/account-server/characterdata.cpp b/src/account-server/characterdata.cpp
index d82100d5..0e140e3c 100644
--- a/src/account-server/characterdata.cpp
+++ b/src/account-server/characterdata.cpp
@@ -22,9 +22,11 @@
#include "account-server/characterdata.hpp"
+#include "account-server/dalstorage.hpp"
+
CharacterData::CharacterData(std::string const &name, int id):
- mDatabaseID(id), mAccountID(-1), mName(name), mGender(0), mHairStyle(0),
- mHairColor(0), mLevel(0), mMapId(0), mPos(0,0)
+ mName(name), mDatabaseID(id), mAccountID(-1), mPos(0,0), mMapId(0),
+ mGender(0), mHairStyle(0), mHairColor(0), mLevel(0)
{
for (int i = 0; i < CHAR_ATTR_NB; ++i)
{
@@ -32,3 +34,8 @@ CharacterData::CharacterData(std::string const &name, int id):
}
}
+int CharacterData::getAccountLevel() const
+{
+ AccountPtr acc = Storage::instance("tmw").getAccountByID(mAccountID);
+ return acc->getLevel();
+}
diff --git a/src/account-server/characterdata.hpp b/src/account-server/characterdata.hpp
index 499b5bef..b1b19d3a 100644
--- a/src/account-server/characterdata.hpp
+++ b/src/account-server/characterdata.hpp
@@ -91,6 +91,13 @@ class CharacterData
void
setHairColor(int color) { mHairColor = color; }
+ /** Gets the account level of the user. */
+ int getAccountLevel() const;
+
+ /** Sets the account level of the user. */
+ void setAccountLevel(int)
+ { /* Ignored as we do not trust game servers that much. */ }
+
/** Gets the level of the character. */
int
getLevel() const { return mLevel; }
@@ -146,19 +153,20 @@ class CharacterData
CharacterData(CharacterData const &);
CharacterData &operator=(CharacterData const &);
+ Possessions mPossessions; //!< All the possesions of the character.
+ std::string mName; //!< Name of the character.
int mDatabaseID; //!< Character database ID.
//!< (-1) if not set yet.
int mAccountID; //!< Account ID of the account the character
//!< belongs to. (-1) if not set yet.
- std::string mName; //!< Name of the character.
- unsigned char mGender; //!< Gender of the being.
- unsigned char mHairStyle; //!< Hair Style of the being.
- unsigned char mHairColor; //!< Hair Color of the being.
- unsigned char mLevel; //!< Level of the being.
+ Point mPos; //!< Position the being is at.
unsigned short mAttributes[CHAR_ATTR_NB]; //!< Attributes.
unsigned short mMapId; //!< Map the being is on.
- Point mPos; //!< Position the being is at.
- Possessions mPossessions; //!< All the possesions of the character.
+ unsigned char mGender; //!< Gender of the being.
+ unsigned char mHairStyle; //!< Hair style of the being.
+ unsigned char mHairColor; //!< Hair color of the being.
+ unsigned char mLevel; //!< Level of the being.
+
std::vector<std::string> mGuilds; //!< All the guilds the player
//!< belongs to.
};
diff --git a/src/chat-server/chatclient.hpp b/src/chat-server/chatclient.hpp
index 40622afe..f08573b2 100644
--- a/src/chat-server/chatclient.hpp
+++ b/src/chat-server/chatclient.hpp
@@ -27,7 +27,6 @@
#include <string>
#include <vector>
-#include "defines.h"
#include "net/netcomputer.hpp"
class ChatChannel;
@@ -43,14 +42,13 @@ class ChatClient : public NetComputer
* Constructor.
*/
ChatClient(ENetPeer *peer):
- NetComputer(peer),
- accountLevel(AL_NORMAL)
+ NetComputer(peer)
{
}
std::string characterName;
std::vector< ChatChannel * > channels;
- AccountLevel accountLevel;
+ unsigned char accountLevel;
};
#endif
diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp
index 8710168d..88b8864b 100644
--- a/src/chat-server/chathandler.cpp
+++ b/src/chat-server/chathandler.cpp
@@ -45,7 +45,7 @@ void registerChatClient(const std::string &token,
{
ChatHandler::Pending *p = new ChatHandler::Pending;
p->character = name;
- p->level = (AccountLevel) level;
+ p->level = level;
chatHandler->mTokenCollector.addPendingConnect(token, p);
}
diff --git a/src/chat-server/chathandler.hpp b/src/chat-server/chathandler.hpp
index 43e70013..301ea303 100644
--- a/src/chat-server/chathandler.hpp
+++ b/src/chat-server/chathandler.hpp
@@ -29,7 +29,6 @@
#include "net/connectionhandler.hpp"
class ChatClient;
-enum AccountLevel;
/**
* Manages chat related things like private messaging, chat channel handling
@@ -48,7 +47,7 @@ class ChatHandler : public ConnectionHandler
struct Pending
{
std::string character;
- AccountLevel level;
+ unsigned char level;
};
public:
diff --git a/src/defines.h b/src/defines.h
index 138094f4..03eb60d0 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -27,22 +27,13 @@
/**
* Enumeration type for account levels.
- *
- * Note the the actual tasks that can be done by admin or gm, or the
- * restrictions on a restricted user, are not specified yet. Also, banned
- * status will probably be derived from a date field (the time until an account
- * is banned).
- *
- * It may be better to wait and see what permissions we'd want to grant to or
- * take from users, and then come up with a convenient way to handle that.
*/
-enum AccountLevel
+enum
{
- AL_NORMAL, // User has regular rights
- AL_ADMIN, // User can perform administrator tasks
- AL_GM, // User can perform a subset of administrator tasks
- AL_BANNED, // This user is currently banned
- AL_RESTRICTED // User rights have been restricted
+ AL_BANNED = 0, /**< This user is currently banned. */
+ AL_NORMAL = 10, /**< User has regular rights. */
+ AL_GM = 50, /**< User can perform a subset of administrator tasks. */
+ AL_ADMIN = 99, /**< User can perform administrator tasks. */
};
enum
diff --git a/src/game-server/character.hpp b/src/game-server/character.hpp
index 62245fc7..2cf4500c 100644
--- a/src/game-server/character.hpp
+++ b/src/game-server/character.hpp
@@ -176,6 +176,14 @@ class Character : public Being
setLevel(int level)
{ mLevel = level; }
+ /** Gets the account level of the user. */
+ int getAccountLevel() const
+ { return mAccountLevel; }
+
+ /** Sets the account level of the user. */
+ void setAccountLevel(int l)
+ { mAccountLevel = l; }
+
/**
* Sends a message that informs the client about attribute
* modified since last call.
@@ -226,6 +234,7 @@ class Character : public Being
unsigned char mHairStyle; /**< Hair Style of the character. */
unsigned char mHairColor; /**< Hair Color of the character. */
unsigned char mLevel; /**< Level of the character. */
+ unsigned char mAccountLevel; /**< Account level of the user. */
TransactionType mTransaction; /**< Trade/buy/sell action the character is involved in. */
};
diff --git a/src/game-server/command.cpp b/src/game-server/command.cpp
new file mode 100644
index 00000000..2920c30a
--- /dev/null
+++ b/src/game-server/command.cpp
@@ -0,0 +1,223 @@
+/*
+ * The Mana World Server
+ * Copyright 2007 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World 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
+ * any later version.
+ *
+ * The Mana World 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 The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#include <cstddef>
+
+#include "defines.h"
+#include "game-server/character.hpp"
+#include "game-server/inventory.hpp"
+#include "game-server/item.hpp"
+#include "game-server/itemmanager.hpp"
+#include "game-server/mapmanager.hpp"
+#include "game-server/state.hpp"
+
+template< typename T1, typename T2, typename T3 >
+static void proxy(void (*f)(), intptr_t args[4])
+{
+ ((void (*)(T1, T2, T3))f)((T1)args[0], (T2)args[1], (T3)args[2]);
+}
+
+template< typename T1, typename T2, typename T3, typename T4 >
+static void proxy(void (*f)(), intptr_t args[4])
+{
+ ((void (*)(T1, T2, T3, T4))f)((T1)args[0], (T2)args[1], (T3)args[2], (T4)args[3]);
+}
+
+/**
+ * An argument type that a command can use.
+ */
+
+template< typename T > struct Argument;
+
+template<> struct Argument< int >
+{ static char const type = 'n'; };
+template<> struct Argument< Character * >
+{ static char const type = 'c'; };
+template<> struct Argument< MapComposite * >
+{ static char const type = 'm'; };
+template<> struct Argument< ItemClass * >
+{ static char const type = 'i'; };
+
+/**
+ * A command that a user can run remotely with sufficient rights.
+ */
+struct Command
+{
+ char const *name;
+ char type[4];
+ void (*handler)(void (*f)(), intptr_t[4]);
+ void (*target)();
+ unsigned char level;
+};
+
+/**
+ * Creates a command with a 3-parameter handler.
+ */
+template< typename T1, typename T2, typename T3 >
+static Command handle(char const *name, int level, void (*f)(T1, T2, T3))
+{
+ Command c;
+ c.name = name;
+ c.level = level;
+ c.handler = &proxy< T1, T2, T3 >;
+ c.target = (void (*)())f;
+ c.type[0] = Argument<T1>::type;
+ c.type[1] = Argument<T2>::type;
+ c.type[2] = Argument<T3>::type;
+ c.type[3] = 0;
+ return c;
+}
+
+/**
+ * Creates a command with a 4-parameter handler.
+ */
+template< typename T1, typename T2, typename T3, typename T4 >
+static Command handle(char const *name, int level, void (*f)(T1, T2, T3, T4))
+{
+ Command c;
+ c.name = name;
+ c.level = level;
+ c.handler = &proxy< T1, T2, T3, T4 >;
+ c.target = (void (*)())f;
+ c.type[0] = Argument<T1>::type;
+ c.type[1] = Argument<T2>::type;
+ c.type[2] = Argument<T3>::type;
+ c.type[3] = Argument<T4>::type;
+ return c;
+}
+
+static void warp(Character *q, MapComposite *m, int x, int y)
+{
+ DelayedEvent e = { EVENT_WARP, x, y, m };
+ GameState::enqueueEvent(q, e);
+}
+
+static void item(Character *q, ItemClass *it, int nb)
+{
+ Inventory(q).insert(it->getDatabaseID(), nb);
+}
+
+/**
+ * List of remote commands.
+ */
+static Command const commands[] =
+{
+ handle("warp", AL_GM, warp),
+ handle("item", AL_GM, item),
+};
+
+/**
+ * Parses a command and executes its associated handler.
+ */
+void runCommand(Character *ch, std::string const &text)
+{
+ Command const *c = NULL;
+ std::string::size_type npos = std::string::npos;
+ std::string::size_type pos = text.find(' ');
+ std::string s(text, 1, pos == npos ? npos : pos - 1); // Skip slash.
+
+ for (int i = 0; i < (int)(sizeof(commands) / sizeof(commands[0])); ++i)
+ {
+ if (s == commands[i].name)
+ {
+ c = &commands[i];
+ break;
+ }
+ }
+
+ if (!c || c->level < ch->getAccountLevel())
+ {
+ // No such command or no sufficient rights.
+ return;
+ }
+
+ intptr_t args[4];
+
+ for (int i = 0; i < 4 && c->type[i]; ++i)
+ {
+ if (pos == npos || pos + 1 >= text.length())
+ {
+ // Not enough parameters.
+ return;
+ }
+
+ std::string::size_type pos2 = text.find(' ', pos + 1);
+ std::string arg(text, pos + 1, pos2 == npos ? npos : pos2 - pos - 1);
+ if (arg.empty())
+ {
+ // Empty parameter.
+ return;
+ }
+
+ switch (c->type[i])
+ {
+ case 'c':
+ if (arg == "#")
+ {
+ // Character itself.
+ args[i] = (intptr_t)ch;
+ }
+ else
+ {
+ // TODO: explicitly named character.
+ return;
+ }
+ break;
+
+ case 'i':
+ if (ItemClass *ic = ItemManager::getItem(atoi(arg.c_str())))
+ {
+ args[i] = (intptr_t)ic;
+ }
+ else
+ {
+ // No such item.
+ return;
+ }
+ break;
+
+ case 'm':
+ if (arg == "#")
+ {
+ // Map the character is on.
+ args[i] = (intptr_t)ch->getMap();
+ }
+ else if (MapComposite *m = MapManager::getMap(atoi(arg.c_str())))
+ {
+ args[i] = (intptr_t)m;
+ }
+ else
+ {
+ // No such map.
+ return;
+ }
+ break;
+
+ case 'n':
+ args[i] = atoi(arg.c_str());
+ break;
+ }
+ pos = pos2;
+ }
+ c->handler(c->target, args);
+}
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp
index f02cc450..df72c6b7 100644
--- a/src/game-server/gamehandler.cpp
+++ b/src/game-server/gamehandler.cpp
@@ -166,6 +166,15 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
case PGMSG_SAY:
{
std::string say = message.readString();
+ if (say.empty()) break;
+
+ if (say[0] == '/')
+ {
+ // Handle special command.
+ extern void runCommand(Character *, std::string const &);
+ runCommand(computer.character, say);
+ break;
+ }
GameState::sayAround(computer.character, say);
} break;
diff --git a/src/serialize/characterdata.hpp b/src/serialize/characterdata.hpp
index b1ccc6d5..7d3a7fc1 100644
--- a/src/serialize/characterdata.hpp
+++ b/src/serialize/characterdata.hpp
@@ -32,6 +32,7 @@
template< class T >
void serializeCharacterData(T const &data, MessageOut &msg)
{
+ msg.writeByte(data.getAccountLevel());
msg.writeByte(data.getGender());
msg.writeByte(data.getHairStyle());
msg.writeByte(data.getHairColor());
@@ -64,6 +65,7 @@ void serializeCharacterData(T const &data, MessageOut &msg)
template< class T >
void deserializeCharacterData(T &data, MessageIn &msg)
{
+ data.setAccountLevel(msg.readByte());
data.setGender(msg.readByte());
data.setHairStyle(msg.readByte());
data.setHairColor(msg.readByte());