diff --git a/amxmodx/AMBuilder b/amxmodx/AMBuilder
index 034ff488..78389dcf 100644
--- a/amxmodx/AMBuilder
+++ b/amxmodx/AMBuilder
@@ -92,6 +92,8 @@ binary.sources = [
'CFlagManager.cpp',
'datastructs.cpp',
'trie_natives.cpp',
+ 'CDataPack.cpp',
+ 'datapacks.cpp'
]
if builder.target_platform == 'windows':
diff --git a/amxmodx/CDataPack.cpp b/amxmodx/CDataPack.cpp
new file mode 100644
index 00000000..8e6c45b7
--- /dev/null
+++ b/amxmodx/CDataPack.cpp
@@ -0,0 +1,259 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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 .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#include
+#include
+#include "CDataPack.h"
+
+#define DATAPACK_INITIAL_SIZE 512
+
+CDataPack::CDataPack()
+{
+ m_pBase = (char *)malloc(DATAPACK_INITIAL_SIZE);
+ m_capacity = DATAPACK_INITIAL_SIZE;
+ Initialize();
+}
+
+CDataPack::~CDataPack()
+{
+ free(m_pBase);
+}
+
+void CDataPack::Initialize()
+{
+ m_curptr = m_pBase;
+ m_size = 0;
+}
+
+void CDataPack::CheckSize(size_t typesize)
+{
+ if (m_curptr - m_pBase + typesize <= m_capacity)
+ {
+ return;
+ }
+
+ size_t pos = m_curptr - m_pBase;
+ do
+ {
+ m_capacity *= 2;
+ m_pBase = (char *)realloc(m_pBase, m_capacity);
+ m_curptr = m_pBase + pos;
+ } while (m_curptr - m_pBase + typesize > m_capacity);
+}
+
+void CDataPack::ResetSize()
+{
+ m_size = 0;
+}
+
+size_t CDataPack::CreateMemory(size_t size, void **addr)
+{
+ CheckSize(sizeof(size_t) + size);
+ size_t pos = m_curptr - m_pBase;
+
+ *(size_t *)m_curptr = size;
+ m_curptr += sizeof(size_t);
+
+ if (addr)
+ {
+ *addr = m_curptr;
+ }
+
+ m_curptr += size;
+ m_size += sizeof(size_t) + size;
+
+ return pos;
+}
+
+void CDataPack::PackCell(cell cells)
+{
+ CheckSize(sizeof(size_t) + sizeof(cell));
+
+ *(size_t *)m_curptr = sizeof(cell);
+ m_curptr += sizeof(size_t);
+
+ *(cell *)m_curptr = cells;
+ m_curptr += sizeof(cell);
+
+ m_size += sizeof(size_t) + sizeof(cell);
+}
+
+void CDataPack::PackFloat(float val)
+{
+ CheckSize(sizeof(size_t) + sizeof(float));
+
+ *(size_t *)m_curptr = sizeof(float);
+ m_curptr += sizeof(size_t);
+
+ *(float *)m_curptr = val;
+ m_curptr += sizeof(float);
+
+ m_size += sizeof(size_t) + sizeof(float);
+}
+
+void CDataPack::PackString(const char *string)
+{
+ size_t len = strlen(string);
+ size_t maxsize = sizeof(size_t) + len + 1;
+ CheckSize(maxsize);
+
+ // Pack the string length first for buffer overrun checking.
+ *(size_t *)m_curptr = len;
+ m_curptr += sizeof(size_t);
+
+ // Now pack the string.
+ memcpy(m_curptr, string, len);
+ m_curptr[len] = '\0';
+ m_curptr += len + 1;
+
+ m_size += maxsize;
+}
+
+void CDataPack::Reset() const
+{
+ m_curptr = m_pBase;
+}
+
+size_t CDataPack::GetPosition() const
+{
+ return static_cast(m_curptr - m_pBase);
+}
+
+bool CDataPack::SetPosition(size_t pos) const
+{
+ if (pos > m_size-1)
+ {
+ return false;
+ }
+ m_curptr = m_pBase + pos;
+
+ return true;
+}
+
+cell CDataPack::ReadCell() const
+{
+ if (!IsReadable(sizeof(size_t) + sizeof(cell)))
+ {
+ return 0;
+ }
+ if (*reinterpret_cast(m_curptr) != sizeof(cell))
+ {
+ return 0;
+ }
+
+ m_curptr += sizeof(size_t);
+
+ cell val = *reinterpret_cast(m_curptr);
+ m_curptr += sizeof(cell);
+ return val;
+}
+
+float CDataPack::ReadFloat() const
+{
+ if (!IsReadable(sizeof(size_t) + sizeof(float)))
+ {
+ return 0;
+ }
+ if (*reinterpret_cast(m_curptr) != sizeof(float))
+ {
+ return 0;
+ }
+
+ m_curptr += sizeof(size_t);
+
+ float val = *reinterpret_cast(m_curptr);
+ m_curptr += sizeof(float);
+ return val;
+}
+
+bool CDataPack::IsReadable(size_t bytes) const
+{
+ return (bytes + (m_curptr - m_pBase) > m_size) ? false : true;
+}
+
+const char *CDataPack::ReadString(size_t *len) const
+{
+ if (!IsReadable(sizeof(size_t)))
+ {
+ return NULL;
+ }
+
+ size_t real_len = *(size_t *)m_curptr;
+
+ m_curptr += sizeof(size_t);
+ char *str = (char *)m_curptr;
+
+ if ((strlen(str) != real_len) || !(IsReadable(real_len+1)))
+ {
+ return NULL;
+ }
+
+ if (len)
+ {
+ *len = real_len;
+ }
+
+ m_curptr += real_len + 1;
+
+ return str;
+}
+
+void *CDataPack::GetMemory() const
+{
+ return m_curptr;
+}
+
+void *CDataPack::ReadMemory(size_t *size) const
+{
+ if (!IsReadable(sizeof(size_t)))
+ {
+ return NULL;
+ }
+
+ size_t bytecount = *(size_t *)m_curptr;
+ m_curptr += sizeof(size_t);
+
+ if (!IsReadable(bytecount))
+ {
+ return NULL;
+ }
+
+ void *ptr = m_curptr;
+
+ if (size)
+ {
+ *size = bytecount;
+ }
+
+ m_curptr += bytecount;
+
+ return ptr;
+}
diff --git a/amxmodx/CDataPack.h b/amxmodx/CDataPack.h
new file mode 100644
index 00000000..491b2920
--- /dev/null
+++ b/amxmodx/CDataPack.h
@@ -0,0 +1,244 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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 .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#ifndef _INCLUDE_SOURCEMOD_CDATAPACK_H_
+#define _INCLUDE_SOURCEMOD_CDATAPACK_H_
+
+#include "amxmodx.h"
+
+/**
+ * @brief Contains functions for packing data abstractly to/from plugins.
+ */
+class CDataPack
+{
+public:
+ CDataPack();
+ ~CDataPack();
+
+public:
+ /**
+ * @brief Resets the position in the data stream to the beginning.
+ */
+ void Reset() const;
+
+ /**
+ * @brief Retrieves the current stream position.
+ *
+ * @return Index into the stream.
+ */
+ size_t GetPosition() const;
+
+ /**
+ * @brief Sets the current stream position.
+ *
+ * @param pos Index to set the stream at.
+ * @return True if succeeded, false if out of bounds.
+ */
+ bool SetPosition(size_t pos) const;
+
+ /**
+ * @brief Reads one cell from the data stream.
+ *
+ * @return A cell read from the current position.
+ */
+ cell ReadCell() const;
+
+ /**
+ * @brief Reads one float from the data stream.
+ *
+ * @return A float read from the current position.
+ */
+ float ReadFloat() const;
+
+ /**
+ * @brief Returns whether or not a specified number of bytes from the current stream
+ * position to the end can be read.
+ *
+ * @param bytes Number of bytes to simulate reading.
+ * @return True if can be read, false otherwise.
+ */
+ bool IsReadable(size_t bytes) const;
+
+ /**
+ * @brief Reads a string from the data stream.
+ *
+ * @param len Optional pointer to store the string length.
+ * @return Pointer to the string, or NULL if out of bounds.
+ */
+ const char *ReadString(size_t *len) const;
+
+ /**
+ * @brief Reads the current position as a generic address.
+ *
+ * @return Pointer to the memory.
+ */
+ void *GetMemory() const;
+
+ /**
+ * @brief Reads the current position as a generic data type.
+ *
+ * @param size Optional pointer to store the size of the data type.
+ * @return Pointer to the data, or NULL if out of bounds.
+ */
+ void *ReadMemory(size_t *size) const;
+
+public:
+ /**
+ * @brief Resets the used size of the stream back to zero.
+ */
+ void ResetSize();
+
+ /**
+ * @brief Packs one cell into the data stream.
+ *
+ * @param cell Cell value to write.
+ */
+ void PackCell(cell cells);
+
+ /**
+ * @brief Packs one float into the data stream.
+ *
+ * @param val Float value to write.
+ */
+ void PackFloat(float val);
+
+ /**
+ * @brief Packs one string into the data stream.
+ * The length is recorded as well for buffer overrun protection.
+ *
+ * @param string String to write.
+ */
+ void PackString(const char *string);
+
+ /**
+ * @brief Creates a generic block of memory in the stream.
+ *
+ * Note that the pointer it returns can be invalidated on further
+ * writing, since the stream size may grow. You may need to double back
+ * and fetch the pointer again.
+ *
+ * @param size Size of the memory to create in the stream.
+ * @param addr Optional pointer to store the relocated memory address.
+ * @return Current position of the stream beforehand.
+ */
+ size_t CreateMemory(size_t size, void **addr);
+
+public:
+ void Initialize();
+
+private:
+ void CheckSize(size_t sizetype);
+
+private:
+ char *m_pBase;
+ mutable char *m_curptr;
+ size_t m_capacity;
+ size_t m_size;
+};
+
+class CDataPackHandles
+{
+private:
+ CVector m_packs;
+
+public:
+ CDataPackHandles() {}
+ ~CDataPackHandles()
+ {
+ this->clear();
+ }
+
+ void clear()
+ {
+ for (size_t i = 0; i < m_packs.size(); i++)
+ {
+ if (m_packs[i] != NULL)
+ {
+ delete m_packs[i];
+ }
+ }
+
+ m_packs.clear();
+ }
+
+ CDataPack *lookup(int handle)
+ {
+ handle--;
+
+ if (handle < 0 || handle >= static_cast(m_packs.size()))
+ {
+ return NULL;
+ }
+
+ return m_packs[handle];
+ }
+
+ int create()
+ {
+ for (size_t i = 0; i < m_packs.size(); ++i)
+ {
+ if (m_packs[i] == NULL)
+ {
+ // reuse handle
+ m_packs[i] = new CDataPack;
+
+ return static_cast(i) + 1;
+ }
+ }
+ m_packs.push_back(new CDataPack);
+ return m_packs.size();
+ }
+
+ bool destroy(int handle)
+ {
+ handle--;
+
+ if (handle < 0 || handle >= static_cast(m_packs.size()))
+ {
+ return false;
+ }
+
+ if (m_packs[handle] == NULL)
+ {
+ return false;
+ }
+
+ delete m_packs[handle];
+ m_packs[handle] = NULL;
+
+ return true;
+ }
+};
+
+extern CDataPackHandles g_DataPackHandles;
+extern AMX_NATIVE_INFO g_DatapackNatives[];
+
+#endif //_INCLUDE_SOURCEMOD_CDATAPACK_H_
diff --git a/amxmodx/Makefile b/amxmodx/Makefile
index fceded03..71581592 100755
--- a/amxmodx/Makefile
+++ b/amxmodx/Makefile
@@ -21,7 +21,7 @@ OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp \
amxmod_compat.cpp nongpl_matches.cpp CFlagManager.cpp datastructs.cpp \
- trie_natives.cpp
+ trie_natives.cpp CDataPack.cpp datapacks.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
diff --git a/amxmodx/datapacks.cpp b/amxmodx/datapacks.cpp
new file mode 100644
index 00000000..baab9c37
--- /dev/null
+++ b/amxmodx/datapacks.cpp
@@ -0,0 +1,250 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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 .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#include "CDataPack.h"
+
+CDataPackHandles g_DataPackHandles;
+
+static cell AMX_NATIVE_CALL CreateDataPack(AMX* amx, cell* params)
+{
+ return static_cast(g_DataPackHandles.create());
+}
+
+static cell AMX_NATIVE_CALL WritePackCell(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ d->PackCell(params[2]);
+
+ return 1;
+}
+
+static cell AMX_NATIVE_CALL WritePackFloat(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ d->PackFloat(amx_ctof(params[2]));
+
+ return 1;
+}
+
+static cell AMX_NATIVE_CALL WritePackString(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ int len;
+ const char *str = get_amxstring(amx, params[2], 0, len);
+
+ d->PackString(str);
+
+ return len;
+}
+
+static cell AMX_NATIVE_CALL ReadPackCell(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ if (!d->IsReadable(sizeof(size_t) + sizeof(cell)))
+ {
+ LogError(amx, AMX_ERR_NATIVE, "DataPack operation is out of bounds.");
+ return 0;
+ }
+
+ return d->ReadCell();
+}
+
+static cell AMX_NATIVE_CALL ReadPackFloat(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ if (!d->IsReadable(sizeof(size_t) + sizeof(float)))
+ {
+ LogError(amx, AMX_ERR_NATIVE, "DataPack operation is out of bounds.");
+ return 0;
+ }
+
+ float value = d->ReadFloat();
+
+ return amx_ftoc(value);
+}
+
+static cell AMX_NATIVE_CALL ReadPackString(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ const char *str;
+ if (!(str = d->ReadString(NULL)))
+ {
+ LogError(amx, AMX_ERR_NATIVE, "DataPack operation is out of bounds.");
+ return 0;
+ }
+
+ return set_amxstring(amx, params[2], str, params[3]);
+}
+
+static cell AMX_NATIVE_CALL ResetPack(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ d->Reset();
+
+ if (params[2])
+ {
+ d->ResetSize();
+ }
+
+ return 1;
+}
+
+static cell AMX_NATIVE_CALL GetPackPosition(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ return static_cast(d->GetPosition());
+}
+
+static cell AMX_NATIVE_CALL SetPackPosition(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ if (!d->SetPosition(params[2]))
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid DataPack position, %d is out of bounds", params[2]);
+ return 0;
+ }
+
+ return 1;
+}
+
+static cell AMX_NATIVE_CALL IsPackReadable(AMX* amx, cell* params)
+{
+ CDataPack *d = g_DataPackHandles.lookup(params[1]);
+
+ if (d == NULL)
+ {
+ LogError(amx, AMX_ERR_NATIVE, "Invalid datapack handle provided (%d)", params[1]);
+ return 0;
+ }
+
+ return d->IsReadable(params[2]) ? 1 : 0;
+}
+
+static cell AMX_NATIVE_CALL DestroyDataPack(AMX* amx, cell* params)
+{
+ cell *ptr = get_amxaddr(amx, params[1]);
+
+ CDataPack *d = g_DataPackHandles.lookup(*ptr);
+
+ if (d == NULL)
+ {
+ return 0;
+ }
+
+ if (g_DataPackHandles.destroy(*ptr))
+ {
+ *ptr = 0;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+AMX_NATIVE_INFO g_DatapackNatives[] =
+{
+ { "CreateDataPack", CreateDataPack },
+ { "WritePackCell", WritePackCell },
+ { "WritePackFloat", WritePackFloat },
+ { "WritePackString", WritePackString },
+ { "ReadPackCell", ReadPackCell },
+ { "ReadPackFloat", ReadPackFloat },
+ { "ReadPackString", ReadPackString },
+ { "ResetPack", ResetPack },
+ { "GetPackPosition", GetPackPosition },
+ { "SetPackPosition", SetPackPosition },
+ { "IsPackReadable", IsPackReadable },
+ { "DestroyDataPack", DestroyDataPack },
+ {NULL, NULL}
+};
diff --git a/amxmodx/meta_api.cpp b/amxmodx/meta_api.cpp
index 0e5e194c..204f4069 100755
--- a/amxmodx/meta_api.cpp
+++ b/amxmodx/meta_api.cpp
@@ -52,6 +52,7 @@
#include "CFlagManager.h"
#include
#include "trie_natives.h"
+#include "CDataPack.h"
plugin_info_t Plugin_info =
{
@@ -413,6 +414,8 @@ int C_Spawn(edict_t *pent)
VectorHolder.clear();
g_TrieHandles.clear();
+ g_DataPackHandles.clear();
+
char map_pluginsfile_path[256];
char prefixed_map_pluginsfile[256];
char configs_dir[256];
diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp
index 23e6a6ff..c7f8e0cf 100755
--- a/amxmodx/modules.cpp
+++ b/amxmodx/modules.cpp
@@ -53,6 +53,7 @@
#include "messages.h"
#include "amxmod_compat.h"
#include "trie_natives.h"
+#include "CDataPack.h"
CList g_modules;
CList g_loadedscripts;
@@ -587,6 +588,7 @@ int set_amxnatives(AMX* amx, char error[128])
amx_Register(amx, g_SortNatives, -1);
amx_Register(amx, g_DataStructNatives, -1);
amx_Register(amx, trie_Natives, -1);
+ amx_Register(amx, g_DatapackNatives, -1);
if (amx->flags & AMX_FLAG_OLDFILE)
{
diff --git a/amxmodx/msvc10/amxmodx_mm.vcxproj b/amxmodx/msvc10/amxmodx_mm.vcxproj
index c9ab3453..814224ba 100644
--- a/amxmodx/msvc10/amxmodx_mm.vcxproj
+++ b/amxmodx/msvc10/amxmodx_mm.vcxproj
@@ -295,6 +295,7 @@
true
+
@@ -307,6 +308,7 @@
+
@@ -354,6 +356,7 @@
+
@@ -397,6 +400,7 @@
+
diff --git a/amxmodx/msvc10/amxmodx_mm.vcxproj.filters b/amxmodx/msvc10/amxmodx_mm.vcxproj.filters
index 5e572549..88fe2a64 100644
--- a/amxmodx/msvc10/amxmodx_mm.vcxproj.filters
+++ b/amxmodx/msvc10/amxmodx_mm.vcxproj.filters
@@ -174,6 +174,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
@@ -314,6 +320,9 @@
SDK
+
+ Header Files
+
@@ -423,6 +432,9 @@
Pawn Includes
+
+ Pawn Includes
+
| | |