From 72dfb51de2bb766d291d2d3134e3f34b679281c7 Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Wed, 19 Jul 2017 20:29:11 +0300
Subject: Add support for loading permissions from groups.xml

---
 src/CMakeLists.txt                         |  2 +
 src/Makefile.am                            |  1 +
 src/enums/resources/serverpermissiontype.h | 41 ++++-------------
 src/resources/db/groupdb.cpp               | 72 ++++++++++++++++++++++++++++--
 src/resources/serverpermissions.inc        | 54 ++++++++++++++++++++++
 5 files changed, 134 insertions(+), 36 deletions(-)
 create mode 100644 src/resources/serverpermissions.inc

(limited to 'src')

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 65d84e1b8..7c41804c3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -835,6 +835,7 @@ SET(SRCS
     resources/db/weaponsdb.cpp
     resources/db/weaponsdb.h
     resources/servercommands.inc
+    resources/serverpermissions.inc
     resources/soundeffect.cpp
     resources/soundeffect.h
     resources/soundinfo.h
@@ -1795,6 +1796,7 @@ SET(DYE_CMD_SRCS
     resources/sdlmusic.h
     resources/skillconsts.h
     resources/servercommands.inc
+    resources/serverpermissions.inc
     resources/soundeffect.cpp
     resources/soundeffect.h
     resources/image/subimage.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index ad74aa51a..fe70cd2ef 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -550,6 +550,7 @@ BASE_SRC += events/actionevent.h \
 	      enums/resources/skill/skilltype.h \
 	      enums/resources/skill/skilltype2.h \
 	      resources/servercommands.inc \
+	      resources/serverpermissions.inc \
 	      resources/soundeffect.cpp \
 	      resources/soundeffect.h \
 	      resources/soundinfo.h \
diff --git a/src/enums/resources/serverpermissiontype.h b/src/enums/resources/serverpermissiontype.h
index bee1d2d37..338377624 100644
--- a/src/enums/resources/serverpermissiontype.h
+++ b/src/enums/resources/serverpermissiontype.h
@@ -23,44 +23,19 @@
 
 #include "enums/simpletypes/enumdefines.h"
 
+#define serverpermissionFirst(name) name = 0,
+#define serverpermission(name) name,
+
 enumStart(ServerPermissionType)
 {
-// Hercules permissions
-    can_trade = 0,
-    can_party,
-    all_skill,
-    all_equipment,
-    skill_unconditional,
-    join_chat,
-    kick_chat,
-    hide_session,
-    who_display_aid,
-    hack_info,
-    any_warp,
-    view_hpmeter,
-    view_equipment,
-    use_check,
-    use_changemaptype,
-    all_commands,
-    receive_requests,
-    show_bossmobs,
-    disable_pvm,
-    disable_pvp,
-    disable_commands_when_dead,
-    hchsys_admin,
-    can_trade_bound,
-    disable_pickup,
-    disable_store,
-    disable_exp,
-    disable_skill_usage,
-
-// Evol permissions
-    send_gm,
-    show_client_version,
-
+#include "resources/serverpermissions.inc"
     Max
 }
 enumEnd(ServerPermissionType);
 
+#undef serverpermissionFirst
+#undef serverpermission
+
+SERVERPERMISSION_VOID
 #endif  // ENUMS_RESOURCES_SERVERPERMISSIONTYPE_H
 
diff --git a/src/resources/db/groupdb.cpp b/src/resources/db/groupdb.cpp
index d75a5f29d..b2e1ca011 100644
--- a/src/resources/db/groupdb.cpp
+++ b/src/resources/db/groupdb.cpp
@@ -60,8 +60,8 @@ void GroupDb::load()
         return ServerCommandType::name1; \
     else
 
-static ServerCommandTypeT parseName(const std::string &str,
-                                    const int id)
+static ServerCommandTypeT parseCommand(const std::string &str,
+                                       const int id)
 {
 #include "resources/servercommands.inc"
     {
@@ -77,6 +77,33 @@ static ServerCommandTypeT parseName(const std::string &str,
 #undef servercommand
 #undef servercommand2
 
+#define serverpermissionFirst(name) \
+    if (str == #name) \
+        return ServerPermissionType::name; \
+    else
+#define serverpermission(name) \
+    if (str == #name) \
+        return ServerPermissionType::name; \
+    else
+
+static ServerPermissionTypeT parsePermission(const std::string &str,
+                                             const int id)
+{
+#include "resources/serverpermissions.inc"
+    {
+        reportAlways("GroupsDb: unknown permission name: "
+            "'%s' in group id '%d'.",
+            str.c_str(),
+            id);
+    }
+
+    return ServerPermissionType::Max;
+}
+
+SERVERPERMISSION_VOID
+#undef serverpermissionFirst
+#undef serverpermission
+
 static ServerCommandEnable::Type parseUseFlag(const std::string &str,
                                               const int id)
 {
@@ -92,6 +119,10 @@ static ServerCommandEnable::Type parseUseFlag(const std::string &str,
     {
         return ServerCommandEnable::Both;
     }
+    else if (str == "false")
+    {
+        return ServerCommandEnable::No;
+    }
     else
     {
         reportAlways("GroupsDb: unknown use flag: '%s' in group id '%d'."
@@ -119,7 +150,7 @@ static void loadCommands(XmlNodePtr rootNode,
             const std::string useStr = XML::getProperty(node,
                 "use",
                 "");
-            ServerCommandTypeT name = parseName(nameStr, id);
+            ServerCommandTypeT name = parseCommand(nameStr, id);
             if (name == ServerCommandType::Max)
                 continue;
             ServerCommandEnable::Type useFlag = parseUseFlag(useStr, id);
@@ -130,6 +161,34 @@ static void loadCommands(XmlNodePtr rootNode,
     }
 }
 
+static void loadPermissions(XmlNodePtr rootNode,
+                            const int id,
+                            GroupInfo *groupInfo) A_NONNULL(3);
+static void loadPermissions(XmlNodePtr rootNode,
+                            const int id,
+                            GroupInfo *groupInfo)
+{
+    for_each_xml_child_node(node, rootNode)
+    {
+        if (xmlNameEqual(node, "permission"))
+        {
+            const std::string nameStr = XML::getProperty(node,
+                "name",
+                "");
+            ServerPermissionTypeT perm = parsePermission(nameStr, id);
+            if (perm == ServerPermissionType::Max)
+                continue;
+            if (!XML::getBoolProperty(node,
+                "enable",
+                true))
+            {
+                continue;
+            }
+            groupInfo->mPermissions[CAST_SIZE(perm)] = Enable_true;
+        }
+    }
+}
+
 static void loadSubNodes(XmlNodePtr groupNode,
                          const int id,
                          GroupInfo *groupInfo) A_NONNULL(3);
@@ -141,6 +200,8 @@ static void loadSubNodes(XmlNodePtr groupNode,
     {
         if (xmlNameEqual(node, "commands"))
             loadCommands(node, id, groupInfo);
+        if (xmlNameEqual(node, "permissions"))
+            loadPermissions(node, id, groupInfo);
     }
 }
 
@@ -174,6 +235,11 @@ static void parseInherit(XmlNodePtr groupNode,
             if (enable != ServerCommandEnable::No)
                 groupInfo->mCommands[f] = enable;
         }
+        for (size_t f = 0; f < CAST_SIZE(ServerPermissionType::Max); f ++)
+        {
+            if (groupInfo2->mPermissions[f] == Enable_true)
+                groupInfo->mPermissions[f] = Enable_true;
+        }
     }
 }
 
diff --git a/src/resources/serverpermissions.inc b/src/resources/serverpermissions.inc
new file mode 100644
index 000000000..377c3ab98
--- /dev/null
+++ b/src/resources/serverpermissions.inc
@@ -0,0 +1,54 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2017  The ManaPlus Developers
+ *
+ *  This file is part of The ManaPlus Client.
+ *
+ *  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
+ *  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/>.
+ */
+
+#define SERVERPERMISSION_VOID
+
+// Hercules permissions
+serverpermissionFirst(can_trade)
+serverpermission(can_party)
+serverpermission(all_skill)
+serverpermission(all_equipment)
+serverpermission(skill_unconditional)
+serverpermission(join_chat)
+serverpermission(kick_chat)
+serverpermission(hide_session)
+serverpermission(who_display_aid)
+serverpermission(hack_info)
+serverpermission(any_warp)
+serverpermission(view_hpmeter)
+serverpermission(view_equipment)
+serverpermission(use_check)
+serverpermission(use_changemaptype)
+serverpermission(all_commands)
+serverpermission(receive_requests)
+serverpermission(show_bossmobs)
+serverpermission(disable_pvm)
+serverpermission(disable_pvp)
+serverpermission(disable_commands_when_dead)
+serverpermission(hchsys_admin)
+serverpermission(can_trade_bound)
+serverpermission(disable_pickup)
+serverpermission(disable_store)
+serverpermission(disable_exp)
+serverpermission(disable_skill_usage)
+
+// Evol permissions
+serverpermission(send_gm)
+serverpermission(show_client_version)
-- 
cgit v1.2.3-70-g09d2