diff --git a/.gitignore b/.gitignore
index 2c192b5..ef6a5f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,4 +74,7 @@ build/
 bin/akashi
 bin/config/
 bin_tests/
+bin/logs/
+bin/core.lib
+bin/libcore.a
 doxygen/html
diff --git a/core/include/area_data.h b/core/include/area_data.h
index f2d777d..652d3b2 100644
--- a/core/include/area_data.h
+++ b/core/include/area_data.h
@@ -777,7 +777,7 @@ class AreaData : public QObject {
      * @brief Logs a moderator login attempt.
      *
      * @details This is not a duplicated function! When a client uses the `/login` command to log in, the command call
-     * itself is logged with log(), but the outcome of that call is logged here.
+     * itself is logged with logCmd(), but the outcome of that call is logged here.
      *
      * If there was a way to login *without* the command, only this would be logged.
      *
@@ -788,6 +788,17 @@ class AreaData : public QObject {
      */
     void logLogin(const QString &f_clientName_r, const QString &f_clientIpid_r, bool f_success, const QString& f_modname_r) const;
 
+    /**
+     * @brief Logs a command in the area logger.
+     *
+     * @details When a client sends any packet containing `/`, it is sent to this function instead of log().
+     *
+     * @param f_clientName_r The showname of the command sender's character.
+     * @param f_clientIpid_r The IPID of the command sender.
+     * @param f_packet_r The packet that was sent.
+     */
+    void logCmd(const QString& f_clientName_r, const QString& f_clientIpid_r, const QString& f_command_r, const QStringList& f_cmdArgs_r) const;
+
     /**
      * @brief Convenience function over Logger::flush().
      */
diff --git a/core/include/logger.h b/core/include/logger.h
index a35fde1..59c1443 100644
--- a/core/include/logger.h
+++ b/core/include/logger.h
@@ -82,7 +82,7 @@ public slots:
      * @param f_ipid_r The IPID of the aforementioned client.
      * @param f_oocMessage_r The text of the OOC message. Passed to logOOC() if the command is not 'special' (see details).
      */
-    void logCmd(const QString& f_charName_r, const QString& f_ipid_r, const QString& f_oocMessage_r);
+    void logCmd(const QString& f_charName_r, const QString& f_ipid_r, const QString& f_command_r, const QStringList& f_cmdArgs_r);
 
     /**
      * @brief Logs a login attempt.
diff --git a/core/src/area_data.cpp b/core/src/area_data.cpp
index 17dd7b8..6ef0e9b 100644
--- a/core/src/area_data.cpp
+++ b/core/src/area_data.cpp
@@ -296,7 +296,7 @@ void AreaData::log(const QString &f_clientName_r, const QString &f_clientIpid_r,
     if (l_header == "MS") {
         m_logger->logIC(f_clientName_r, f_clientIpid_r, f_packet_r.contents.at(4));
     } else if (l_header == "CT") {
-        m_logger->logCmd(f_clientName_r, f_clientIpid_r, f_packet_r.contents.at(1));
+        m_logger->logOOC(f_clientName_r, f_clientIpid_r, f_packet_r.contents.at(1));
     } else if (l_header == "ZZ") {
         m_logger->logModcall(f_clientName_r, f_clientIpid_r, f_packet_r.contents.at(0));
     }
@@ -307,6 +307,11 @@ void AreaData::logLogin(const QString &f_clientName_r, const QString &f_clientIp
     m_logger->logLogin(f_clientName_r, f_clientIpid_r, f_success, f_modname_r);
 }
 
+void AreaData::logCmd(const QString &f_clientName_r, const QString &f_clientIpid_r, const QString &f_command_r, const QStringList &f_cmdArgs_r) const
+{
+    m_logger->logCmd(f_clientName_r, f_clientIpid_r, f_command_r, f_cmdArgs_r);
+}
+
 void AreaData::flushLogs() const
 {
     m_logger->flush();
diff --git a/core/src/logger.cpp b/core/src/logger.cpp
index 260acb7..c7dc6ec 100644
--- a/core/src/logger.cpp
+++ b/core/src/logger.cpp
@@ -35,27 +35,22 @@ void Logger::logModcall(const QString& f_charName_r, const QString& f_ipid_r, co
     addEntry(f_charName_r, f_ipid_r, "MODCALL", f_modcallReason_r);
 }
 
-void Logger::logCmd(const QString& f_charName_r, const QString& f_ipid_r, const QString& f_oocMessage_r)
+void Logger::logCmd(const QString& f_charName_r, const QString& f_ipid_r, const QString& f_command_r, const QStringList& f_cmdArgs_r)
 {
-    // I don't like this, but oh well.
-    auto l_cmdArgs = f_oocMessage_r.split(" ", QString::SplitBehavior::SkipEmptyParts);
-    auto l_cmd = l_cmdArgs.at(0).trimmed().toLower();
-    l_cmd = l_cmd.right(l_cmd.length() - 1);
-    l_cmdArgs.removeFirst();
-
     // Some commands contain sensitive data, like passwords
     // These must be filtered out
-    if (l_cmd == "login") {
+    if (f_command_r == "login") {
         addEntry(f_charName_r, f_ipid_r, "LOGIN", "Attempted login");
     }
-    else if (l_cmd == "rootpass") {
+    else if (f_command_r == "rootpass") {
         addEntry(f_charName_r, f_ipid_r, "USERS", "Root password created");
     }
-    else if (l_cmd == "adduser" && !l_cmdArgs.isEmpty()) {
-        addEntry(f_charName_r, f_ipid_r, "USERS", "Added user " + l_cmdArgs.at(0));
+    else if (f_command_r == "adduser" && !f_cmdArgs_r.isEmpty()) {
+        addEntry(f_charName_r, f_ipid_r, "USERS", "Added user " + f_cmdArgs_r.at(0));
     }
     else {
-        logOOC(f_charName_r, f_ipid_r, f_oocMessage_r);
+        QString message = "/" + f_command_r + f_cmdArgs_r.join(" ");
+        logOOC(f_charName_r, f_ipid_r, message);
     }
 }
 
diff --git a/core/src/packets.cpp b/core/src/packets.cpp
index 4c4e0d0..1b65c50 100644
--- a/core/src/packets.cpp
+++ b/core/src/packets.cpp
@@ -214,6 +214,8 @@ void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket p
         int cmd_argc = cmd_argv.length();
 
         handleCommand(command, cmd_argc, cmd_argv);
+        area->logCmd(current_char, ipid, command, cmd_argv);
+        return;
     }
     else {
         server->broadcast(final_packet, current_area);