solocraft + dynamicxp
This commit is contained in:
15
src/tools/CMakeLists.txt
Normal file
15
src/tools/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
add_subdirectory(map_extractor)
|
||||
add_subdirectory(vmap4_assembler)
|
||||
add_subdirectory(vmap4_extractor)
|
||||
add_subdirectory(mmaps_generator)
|
||||
add_subdirectory(web_api)
|
||||
44
src/tools/map_extractor/CMakeLists.txt
Normal file
44
src/tools/map_extractor/CMakeLists.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
|
||||
# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
file(GLOB_RECURSE sources *.cpp *.h)
|
||||
|
||||
include_directories (
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared
|
||||
${CMAKE_SOURCE_DIR}/dep/CascLib/src
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/loadlib
|
||||
)
|
||||
|
||||
include_directories(${include_Dirs})
|
||||
|
||||
add_executable(mapextractor
|
||||
${sources}
|
||||
)
|
||||
|
||||
target_link_libraries(mapextractor
|
||||
casc
|
||||
common
|
||||
g3dlib
|
||||
${BZIP2_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
)
|
||||
|
||||
add_dependencies(mapextractor casc)
|
||||
|
||||
if( UNIX )
|
||||
install(TARGETS mapextractor DESTINATION bin)
|
||||
elseif( WIN32 )
|
||||
install(TARGETS mapextractor DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
1161
src/tools/map_extractor/System.cpp
Normal file
1161
src/tools/map_extractor/System.cpp
Normal file
File diff suppressed because it is too large
Load Diff
240
src/tools/map_extractor/adt.h
Normal file
240
src/tools/map_extractor/adt.h
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef ADT_H
|
||||
#define ADT_H
|
||||
|
||||
#include "loadlib.h"
|
||||
|
||||
#define TILESIZE (533.33333f)
|
||||
#define CHUNKSIZE ((TILESIZE) / 16.0f)
|
||||
#define UNITSIZE (CHUNKSIZE / 8.0f)
|
||||
|
||||
enum LiquidType
|
||||
{
|
||||
LIQUID_TYPE_WATER = 0,
|
||||
LIQUID_TYPE_OCEAN = 1,
|
||||
LIQUID_TYPE_MAGMA = 2,
|
||||
LIQUID_TYPE_SLIME = 3
|
||||
};
|
||||
|
||||
//**************************************************************************************
|
||||
// ADT file class
|
||||
//**************************************************************************************
|
||||
#define ADT_CELLS_PER_GRID 16
|
||||
#define ADT_CELL_SIZE 8
|
||||
#define ADT_GRID_SIZE (ADT_CELLS_PER_GRID*ADT_CELL_SIZE)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
//
|
||||
// Adt file height map chunk
|
||||
//
|
||||
struct adt_MCVT
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
float height_map[(ADT_CELL_SIZE+1)*(ADT_CELL_SIZE+1)+ADT_CELL_SIZE*ADT_CELL_SIZE];
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file liquid map chunk (old)
|
||||
//
|
||||
struct adt_MCLQ
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
float height1;
|
||||
float height2;
|
||||
struct liquid_data{
|
||||
uint32 light;
|
||||
float height;
|
||||
} liquid[ADT_CELL_SIZE+1][ADT_CELL_SIZE+1];
|
||||
|
||||
// 1<<0 - ochen
|
||||
// 1<<1 - lava/slime
|
||||
// 1<<2 - water
|
||||
// 1<<6 - all water
|
||||
// 1<<7 - dark water
|
||||
// == 0x0F - not show liquid
|
||||
uint8 flags[ADT_CELL_SIZE][ADT_CELL_SIZE];
|
||||
uint8 data[84];
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file cell chunk
|
||||
//
|
||||
struct adt_MCNK
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
uint32 flags;
|
||||
uint32 ix;
|
||||
uint32 iy;
|
||||
uint32 nLayers;
|
||||
uint32 nDoodadRefs;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32 offsMCVT; // height map
|
||||
uint32 offsMCNR; // Normal vectors for each vertex
|
||||
} offsets;
|
||||
uint8 HighResHoles[8];
|
||||
} union_5_3_0;
|
||||
uint32 offsMCLY; // Texture layer definitions
|
||||
uint32 offsMCRF; // A list of indices into the parent file's MDDF chunk
|
||||
uint32 offsMCAL; // Alpha maps for additional texture layers
|
||||
uint32 sizeMCAL;
|
||||
uint32 offsMCSH; // Shadow map for static shadows on the terrain
|
||||
uint32 sizeMCSH;
|
||||
uint32 areaid;
|
||||
uint32 nMapObjRefs;
|
||||
uint32 holes;
|
||||
uint16 s[2];
|
||||
uint32 data1;
|
||||
uint32 data2;
|
||||
uint32 data3;
|
||||
uint32 predTex;
|
||||
uint32 nEffectDoodad;
|
||||
uint32 offsMCSE;
|
||||
uint32 nSndEmitters;
|
||||
uint32 offsMCLQ; // Liqid level (old)
|
||||
uint32 sizeMCLQ; //
|
||||
float zpos;
|
||||
float xpos;
|
||||
float ypos;
|
||||
uint32 offsMCCV; // offsColorValues in WotLK
|
||||
uint32 props;
|
||||
uint32 effectId;
|
||||
};
|
||||
|
||||
#define ADT_LIQUID_HEADER_FULL_LIGHT 0x01
|
||||
#define ADT_LIQUID_HEADER_NO_HIGHT 0x02
|
||||
|
||||
struct adt_liquid_header
|
||||
{
|
||||
uint16 liquidType; // Index from LiquidType.dbc
|
||||
uint16 formatFlags;
|
||||
float heightLevel1;
|
||||
float heightLevel2;
|
||||
uint8 xOffset;
|
||||
uint8 yOffset;
|
||||
uint8 width;
|
||||
uint8 height;
|
||||
uint32 offsData2a;
|
||||
uint32 offsData2b;
|
||||
};
|
||||
|
||||
//
|
||||
// Adt file liquid data chunk (new)
|
||||
//
|
||||
struct adt_MH2O
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
|
||||
struct adt_LIQUID{
|
||||
uint32 offsData1;
|
||||
uint32 used;
|
||||
uint32 offsData2;
|
||||
} liquid[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
|
||||
|
||||
adt_liquid_header *getLiquidData(int x, int y)
|
||||
{
|
||||
if (liquid[x][y].used && liquid[x][y].offsData1)
|
||||
return (adt_liquid_header *)((uint8*)this + 8 + liquid[x][y].offsData1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
float *getLiquidHeightMap(adt_liquid_header *h)
|
||||
{
|
||||
if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT)
|
||||
return 0;
|
||||
if (h->offsData2b)
|
||||
return (float *)((uint8*)this + 8 + h->offsData2b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 *getLiquidLightMap(adt_liquid_header *h)
|
||||
{
|
||||
if (h->formatFlags&ADT_LIQUID_HEADER_FULL_LIGHT)
|
||||
return 0;
|
||||
if (h->offsData2b)
|
||||
{
|
||||
if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT)
|
||||
return (uint8 *)((uint8*)this + 8 + h->offsData2b);
|
||||
return (uint8 *)((uint8*)this + 8 + h->offsData2b + (h->width+1)*(h->height+1)*4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 *getLiquidFullLightMap(adt_liquid_header *h)
|
||||
{
|
||||
if (!(h->formatFlags&ADT_LIQUID_HEADER_FULL_LIGHT))
|
||||
return 0;
|
||||
if (h->offsData2b)
|
||||
{
|
||||
if (h->formatFlags & ADT_LIQUID_HEADER_NO_HIGHT)
|
||||
return (uint32 *)((uint8*)this + 8 + h->offsData2b);
|
||||
return (uint32 *)((uint8*)this + 8 + h->offsData2b + (h->width+1)*(h->height+1)*4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 getLiquidShowMap(adt_liquid_header *h)
|
||||
{
|
||||
if (h->offsData2a)
|
||||
return *((uint64 *)((uint8*)this + 8 + h->offsData2a));
|
||||
else
|
||||
return 0xFFFFFFFFFFFFFFFFuLL;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct adt_MFBO
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
struct plane
|
||||
{
|
||||
int16 coords[9];
|
||||
};
|
||||
plane max;
|
||||
plane min;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
209
src/tools/map_extractor/dbcfile.cpp
Normal file
209
src/tools/map_extractor/dbcfile.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#include "dbcfile.h"
|
||||
|
||||
DBCFile::DBCFile(char const* file, char const* fmt)
|
||||
{
|
||||
_file = file;
|
||||
_fmt = fmt;
|
||||
recordTable = nullptr;
|
||||
stringTable = nullptr;
|
||||
fieldsOffset = nullptr;
|
||||
|
||||
header.RecordSize = 0;
|
||||
header.RecordCount = 0;
|
||||
header.FieldCount = 0;
|
||||
header.BlockValue = 0;
|
||||
header.Signature = 0;
|
||||
header.Hash = 0;
|
||||
header.Build = 0;
|
||||
header.TimeStamp = 0;
|
||||
header.Min = 0;
|
||||
header.Max = 0;
|
||||
header.Locale = 0;
|
||||
header.ReferenceDataSize = 0;
|
||||
header.MetaFlags = 0;
|
||||
}
|
||||
|
||||
bool DBCFile::open()
|
||||
{
|
||||
if (recordTable)
|
||||
{
|
||||
delete[] recordTable;
|
||||
recordTable = nullptr;
|
||||
}
|
||||
|
||||
FILE* f = fopen(_file, "rb");
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
if (fread(&header.Signature, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&header.RecordCount, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&header.FieldCount, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&header.RecordSize, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&header.BlockValue, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
fread(&header.Hash, sizeof(uint32), 1, f);
|
||||
fread(&header.Build, sizeof(uint32), 1, f);
|
||||
fread(&header.TimeStamp, sizeof(uint32), 1, f);
|
||||
fread(&header.Min, sizeof(uint32), 1, f);
|
||||
fread(&header.Max, sizeof(uint32), 1, f);
|
||||
fread(&header.Locale, sizeof(uint32), 1, f);
|
||||
fread(&header.ReferenceDataSize, sizeof(uint32), 1, f);
|
||||
//fread(&header.MetaFlags, sizeof(uint32), 1, f);
|
||||
|
||||
recordTable = new unsigned char[header.RecordSize * header.RecordCount + header.BlockValue];
|
||||
stringTable = recordTable + header.RecordSize * header.RecordCount;
|
||||
|
||||
if (fread(recordTable, header.RecordSize * header.RecordCount + header.BlockValue, 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
fieldsOffset = new uint32[header.FieldCount];
|
||||
fieldsOffset[0] = 0;
|
||||
for (uint32 i = 1; i < header.FieldCount; i++)
|
||||
{
|
||||
fieldsOffset[i] = fieldsOffset[i - 1];
|
||||
switch (_fmt[i - 1])
|
||||
{
|
||||
case 'l':
|
||||
fieldsOffset[i] += sizeof(uint64);
|
||||
break;
|
||||
case 'n':
|
||||
case 'i':
|
||||
case 'f':
|
||||
fieldsOffset[i] += sizeof(uint32);
|
||||
break;
|
||||
case 't':
|
||||
fieldsOffset[i] += sizeof(uint16);
|
||||
break;
|
||||
case 'b':
|
||||
fieldsOffset[i] += sizeof(uint8);
|
||||
break;
|
||||
case 's':
|
||||
fieldsOffset[i] += 4/*sizeof(char*)*/; //! WARNING! Size 4
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
DBCFile::~DBCFile()
|
||||
{
|
||||
delete[] recordTable;
|
||||
}
|
||||
|
||||
DBCFile::Record DBCFile::getRecord(size_t id)
|
||||
{
|
||||
assert(recordTable);
|
||||
return Record(*this, recordTable + id * header.RecordSize);
|
||||
}
|
||||
|
||||
float DBCFile::Record::getFloat(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<float*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
uint32 DBCFile::Record::getUInt(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<uint32*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
uint8 DBCFile::Record::getUInt8(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<uint8*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
uint16 DBCFile::Record::getUInt16(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<uint16*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
uint64 DBCFile::Record::getUInt64(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<uint64*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
char const* DBCFile::Record::getString(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return reinterpret_cast<char*>(file.stringTable + getUInt(field));
|
||||
}
|
||||
|
||||
size_t DBCFile::getMaxId()
|
||||
{
|
||||
assert(recordTable);
|
||||
|
||||
size_t maxId = 0;
|
||||
for (size_t i = 0; i < getRecordCount(); ++i)
|
||||
if (maxId < getRecord(i).getUInt(0))
|
||||
maxId = getRecord(i).getUInt(0);
|
||||
|
||||
return maxId;
|
||||
}
|
||||
|
||||
DBCFile::Iterator DBCFile::begin()
|
||||
{
|
||||
assert(recordTable);
|
||||
return Iterator(*this, recordTable);
|
||||
}
|
||||
|
||||
DBCFile::Iterator DBCFile::end()
|
||||
{
|
||||
assert(recordTable);
|
||||
return Iterator(*this, stringTable);
|
||||
}
|
||||
110
src/tools/map_extractor/dbcfile.h
Normal file
110
src/tools/map_extractor/dbcfile.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef DBCFILE_H
|
||||
#define DBCFILE_H
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
#include "Define.h"
|
||||
|
||||
class DBCFile
|
||||
{
|
||||
public:
|
||||
DBCFile(char const* file, char const* fmt);
|
||||
~DBCFile();
|
||||
|
||||
bool open();
|
||||
|
||||
class Iterator;
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
float getFloat(size_t field) const;
|
||||
uint32 getUInt(size_t field) const;
|
||||
uint8 getUInt8(size_t field) const;
|
||||
uint16 getUInt16(size_t field) const;
|
||||
uint64 getUInt64(size_t field) const;
|
||||
char const* getString(size_t field) const;
|
||||
|
||||
private:
|
||||
Record(DBCFile& file, unsigned char* offset) : file(file), offset(offset) { }
|
||||
DBCFile& file;
|
||||
unsigned char* offset;
|
||||
|
||||
friend class DBCFile;
|
||||
friend class DBCFile::Iterator;
|
||||
|
||||
Record& operator=(Record const& right);
|
||||
};
|
||||
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
Iterator(DBCFile &file, unsigned char* offset) : record(file, offset) { }
|
||||
Iterator& operator++()
|
||||
{
|
||||
record.offset += record.file.header.RecordSize;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Record const& operator*() const { return record; }
|
||||
Record const* operator->() const { return &record; }
|
||||
bool operator==(Iterator const& b) const { return record.offset == b.record.offset; }
|
||||
bool operator!=(Iterator const& b) const { return record.offset != b.record.offset; }
|
||||
|
||||
private:
|
||||
Record record;
|
||||
Iterator& operator=(Iterator const& right);
|
||||
};
|
||||
|
||||
Record getRecord(size_t id);
|
||||
uint32 GetOffset(size_t id) const { return (fieldsOffset != nullptr && id < header.FieldCount) ? fieldsOffset[id] : 0; }
|
||||
Iterator begin();
|
||||
Iterator end();
|
||||
size_t getRecordCount() const { return header.RecordCount; }
|
||||
size_t getFieldCount() const { return header.FieldCount; }
|
||||
size_t getMaxId();
|
||||
|
||||
private:
|
||||
uint32* fieldsOffset;
|
||||
char const* _file;
|
||||
unsigned char* recordTable;
|
||||
unsigned char* stringTable;
|
||||
char const* _fmt;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 Signature;
|
||||
uint32 RecordCount;
|
||||
uint32 FieldCount;
|
||||
uint32 RecordSize;
|
||||
uint32 BlockValue;
|
||||
uint32 Hash;
|
||||
uint32 Build;
|
||||
uint32 TimeStamp;
|
||||
uint32 Min;
|
||||
uint32 Max;
|
||||
uint32 Locale;
|
||||
uint32 ReferenceDataSize;
|
||||
uint32 MetaFlags;
|
||||
} header;
|
||||
};
|
||||
|
||||
#endif
|
||||
201
src/tools/map_extractor/loadlib.cpp
Normal file
201
src/tools/map_extractor/loadlib.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#include "loadlib.h"
|
||||
#include <cstdio>
|
||||
|
||||
u_map_fcc MverMagic = { { 'R','E','V','M' } };
|
||||
|
||||
ChunkedFile::ChunkedFile()
|
||||
{
|
||||
data = 0;
|
||||
data_size = 0;
|
||||
}
|
||||
|
||||
ChunkedFile::~ChunkedFile()
|
||||
{
|
||||
free();
|
||||
}
|
||||
|
||||
bool ChunkedFile::loadFile(std::string const& fileName, bool log)
|
||||
{
|
||||
free();
|
||||
FILE* f = fopen(fileName.c_str(), "rb");
|
||||
if (!f)
|
||||
{
|
||||
if (log)
|
||||
printf("No such file %s\n", fileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
data_size = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
data = new uint8[data_size];
|
||||
if (fread(data, data_size, 1, f) != 1)
|
||||
{
|
||||
fprintf(stderr, "ChunkedFile::loadFile Can't read %s, size=%u ferror %s\n", fileName.c_str(), uint32(data_size), strerror(ferror(f)));
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
parseChunks();
|
||||
if (prepareLoadedData())
|
||||
{
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
printf("ChunkedFile::loadFile Error loading %s\n", fileName.c_str());
|
||||
fclose(f);
|
||||
free();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChunkedFile::prepareLoadedData()
|
||||
{
|
||||
FileChunk* chunk = GetChunk("MVER");
|
||||
if (!chunk)
|
||||
return false;
|
||||
|
||||
// Check version
|
||||
file_MVER* version = chunk->As<file_MVER>();
|
||||
if (version->fcc != MverMagic.fcc)
|
||||
return false;
|
||||
if (version->ver != FILE_FORMAT_VERSION)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChunkedFile::free()
|
||||
{
|
||||
for (auto chunk : chunks)
|
||||
delete chunk.second;
|
||||
|
||||
chunks.clear();
|
||||
|
||||
delete[] data;
|
||||
data = 0;
|
||||
data_size = 0;
|
||||
}
|
||||
|
||||
u_map_fcc InterestingChunks[] =
|
||||
{
|
||||
{ { 'R', 'E', 'V', 'M' } },
|
||||
{ { 'N', 'I', 'A', 'M' } },
|
||||
{ { 'O', '2', 'H', 'M' } },
|
||||
{ { 'K', 'N', 'C', 'M' } },
|
||||
{ { 'T', 'V', 'C', 'M' } },
|
||||
{ { 'O', 'M', 'W', 'M' } },
|
||||
{ { 'Q', 'L', 'C', 'M' } },
|
||||
{ { 'O', 'B', 'F', 'M' } }
|
||||
};
|
||||
|
||||
bool IsInterestingChunk(u_map_fcc const& fcc)
|
||||
{
|
||||
for (u_map_fcc const& f : InterestingChunks)
|
||||
if (f.fcc == fcc.fcc)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ChunkedFile::parseChunks()
|
||||
{
|
||||
uint8* ptr = GetData();
|
||||
// Make sure there's enough data to read u_map_fcc struct and the uint32 size after it
|
||||
while (ptr <= GetData() + GetDataSize() - 8)
|
||||
{
|
||||
u_map_fcc header = *(u_map_fcc*)ptr;
|
||||
if (IsInterestingChunk(header))
|
||||
{
|
||||
uint32 size = *(uint32*)(ptr + 4);
|
||||
if (size <= data_size)
|
||||
{
|
||||
std::swap(header.fcc_txt[0], header.fcc_txt[3]);
|
||||
std::swap(header.fcc_txt[1], header.fcc_txt[2]);
|
||||
|
||||
FileChunk* chunk = new FileChunk(ptr, size);
|
||||
chunk->parseSubChunks();
|
||||
chunks.insert({ std::string(header.fcc_txt, 4), chunk });
|
||||
}
|
||||
|
||||
// move to next chunk
|
||||
ptr += size + 8;
|
||||
}
|
||||
else
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
|
||||
FileChunk* ChunkedFile::GetChunk(std::string const& name)
|
||||
{
|
||||
auto range = chunks.equal_range(name);
|
||||
if (std::distance(range.first, range.second) == 1)
|
||||
return range.first->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FileChunk::~FileChunk()
|
||||
{
|
||||
for (auto subchunk : subchunks)
|
||||
delete subchunk.second;
|
||||
|
||||
subchunks.clear();
|
||||
}
|
||||
|
||||
void FileChunk::parseSubChunks()
|
||||
{
|
||||
uint8* ptr = data + 8; // skip self
|
||||
while (ptr < data + size)
|
||||
{
|
||||
u_map_fcc header = *(u_map_fcc*)ptr;
|
||||
if (IsInterestingChunk(header))
|
||||
{
|
||||
uint32 subsize = *(uint32*)(ptr + 4);
|
||||
if (subsize < size)
|
||||
{
|
||||
std::swap(header.fcc_txt[0], header.fcc_txt[3]);
|
||||
std::swap(header.fcc_txt[1], header.fcc_txt[2]);
|
||||
|
||||
FileChunk* chunk = new FileChunk(ptr, subsize);
|
||||
chunk->parseSubChunks();
|
||||
subchunks.insert({ std::string(header.fcc_txt, 4), chunk });
|
||||
}
|
||||
|
||||
// move to next chunk
|
||||
ptr += subsize + 8;
|
||||
}
|
||||
else
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
|
||||
FileChunk* FileChunk::GetSubChunk(std::string const& name)
|
||||
{
|
||||
auto range = subchunks.equal_range(name);
|
||||
if (std::distance(range.first, range.second) == 1)
|
||||
return range.first->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
599
src/tools/map_extractor/loadlib/DBFilesClientList.h
Normal file
599
src/tools/map_extractor/loadlib/DBFilesClientList.h
Normal file
@@ -0,0 +1,599 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef DBFilesClientList_h__
|
||||
#define DBFilesClientList_h__
|
||||
|
||||
char const* DBFilesClientList[] =
|
||||
{
|
||||
"DBFilesClient\\Achievement",
|
||||
"DBFilesClient\\Achievement_Category",
|
||||
"DBFilesClient\\AdventureJournal",
|
||||
"DBFilesClient\\AnimKit",
|
||||
"DBFilesClient\\AnimKitBoneSet",
|
||||
"DBFilesClient\\AnimKitBoneSetAlias",
|
||||
"DBFilesClient\\AnimKitConfig",
|
||||
"DBFilesClient\\AnimKitConfigBoneSet",
|
||||
"DBFilesClient\\AnimKitPriority",
|
||||
"DBFilesClient\\AnimKitSegment",
|
||||
"DBFilesClient\\AnimReplacement",
|
||||
"DBFilesClient\\AnimReplacementSet",
|
||||
"DBFilesClient\\AnimationData",
|
||||
"DBFilesClient\\AreaGroup",
|
||||
"DBFilesClient\\AreaGroupMember",
|
||||
"DBFilesClient\\AreaPOI",
|
||||
"DBFilesClient\\AreaPOIState",
|
||||
"DBFilesClient\\AreaTable",
|
||||
"DBFilesClient\\AreaTrigger",
|
||||
"DBFilesClient\\AreaTriggerActionSet",
|
||||
"DBFilesClient\\AreaTriggerBox",
|
||||
"DBFilesClient\\AreaTriggerCylinder",
|
||||
"DBFilesClient\\AreaTriggerSphere",
|
||||
"DBFilesClient\\ArmorLocation",
|
||||
"DBFilesClient\\AuctionHouse",
|
||||
"DBFilesClient\\BankBagSlotPrices",
|
||||
"DBFilesClient\\BannedAddOns",
|
||||
"DBFilesClient\\BarberShopStyle",
|
||||
"DBFilesClient\\BattlePetAbility",
|
||||
"DBFilesClient\\BattlePetAbilityEffect",
|
||||
"DBFilesClient\\BattlePetAbilityState",
|
||||
"DBFilesClient\\BattlePetAbilityTurn",
|
||||
"DBFilesClient\\BattlePetBreedQuality",
|
||||
"DBFilesClient\\BattlePetBreedState",
|
||||
"DBFilesClient\\BattlePetEffectProperties",
|
||||
"DBFilesClient\\BattlePetNPCTeamMember",
|
||||
"DBFilesClient\\BattlePetSpecies",
|
||||
"DBFilesClient\\BattlePetSpeciesState",
|
||||
"DBFilesClient\\BattlePetSpeciesXAbility",
|
||||
"DBFilesClient\\BattlePetState",
|
||||
"DBFilesClient\\BattlePetVisual",
|
||||
"DBFilesClient\\BattlemasterList",
|
||||
"DBFilesClient\\BroadcastText",
|
||||
"DBFilesClient\\CameraMode",
|
||||
"DBFilesClient\\CameraShakes",
|
||||
"DBFilesClient\\CastableRaidBuffs",
|
||||
"DBFilesClient\\Cfg_Categories",
|
||||
"DBFilesClient\\Cfg_Configs",
|
||||
"DBFilesClient\\Cfg_Regions",
|
||||
"DBFilesClient\\CharBaseInfo",
|
||||
"DBFilesClient\\CharBaseSection",
|
||||
"DBFilesClient\\CharComponentTextureLayouts",
|
||||
"DBFilesClient\\CharComponentTextureSections",
|
||||
"DBFilesClient\\CharHairGeosets",
|
||||
"DBFilesClient\\CharSections",
|
||||
"DBFilesClient\\CharShipment",
|
||||
"DBFilesClient\\CharShipmentContainer",
|
||||
"DBFilesClient\\CharStartOutfit",
|
||||
"DBFilesClient\\CharTitles",
|
||||
"DBFilesClient\\CharacterFaceBoneSet",
|
||||
"DBFilesClient\\CharacterFacialHairStyles",
|
||||
"DBFilesClient\\CharacterLoadout",
|
||||
"DBFilesClient\\CharacterLoadoutItem",
|
||||
"DBFilesClient\\ChatChannels",
|
||||
"DBFilesClient\\ChatProfanity",
|
||||
"DBFilesClient\\ChrClasses",
|
||||
"DBFilesClient\\ChrClassesXPowerTypes",
|
||||
"DBFilesClient\\ChrRaces",
|
||||
"DBFilesClient\\ChrSpecialization",
|
||||
"DBFilesClient\\ChrUpgradeBucket",
|
||||
"DBFilesClient\\ChrUpgradeBucketSpell",
|
||||
"DBFilesClient\\ChrUpgradeTier",
|
||||
"DBFilesClient\\CinematicCamera",
|
||||
"DBFilesClient\\CinematicSequences",
|
||||
"DBFilesClient\\CombatCondition",
|
||||
"DBFilesClient\\Creature",
|
||||
"DBFilesClient\\CreatureDifficulty",
|
||||
"DBFilesClient\\CreatureDisplayInfo",
|
||||
"DBFilesClient\\CreatureDisplayInfoExtra",
|
||||
"DBFilesClient\\CreatureDisplayInfoTrn",
|
||||
"DBFilesClient\\CreatureFamily",
|
||||
"DBFilesClient\\CreatureImmunities",
|
||||
"DBFilesClient\\CreatureModelData",
|
||||
"DBFilesClient\\CreatureMovementInfo",
|
||||
"DBFilesClient\\CreatureSoundData",
|
||||
"DBFilesClient\\CreatureType",
|
||||
"DBFilesClient\\Criteria",
|
||||
"DBFilesClient\\CriteriaTree",
|
||||
"DBFilesClient\\CriteriaTreeXEffect",
|
||||
"DBFilesClient\\CurrencyCategory",
|
||||
"DBFilesClient\\CurrencyTypes",
|
||||
"DBFilesClient\\Curve",
|
||||
"DBFilesClient\\CurvePoint",
|
||||
"DBFilesClient\\DeathThudLookups",
|
||||
"DBFilesClient\\DeclinedWord",
|
||||
"DBFilesClient\\DeclinedWordCases",
|
||||
"DBFilesClient\\DestructibleModelData",
|
||||
"DBFilesClient\\DeviceBlacklist",
|
||||
"DBFilesClient\\DeviceDefaultSettings",
|
||||
"DBFilesClient\\Difficulty",
|
||||
"DBFilesClient\\DriverBlacklist",
|
||||
"DBFilesClient\\DungeonEncounter",
|
||||
"DBFilesClient\\DungeonMap",
|
||||
"DBFilesClient\\DungeonMapChunk",
|
||||
"DBFilesClient\\DurabilityCosts",
|
||||
"DBFilesClient\\DurabilityQuality",
|
||||
"DBFilesClient\\Emotes",
|
||||
"DBFilesClient\\EmotesText",
|
||||
"DBFilesClient\\EmotesTextData",
|
||||
"DBFilesClient\\EmotesTextSound",
|
||||
"DBFilesClient\\EnvironmentalDamage",
|
||||
"DBFilesClient\\Exhaustion",
|
||||
"DBFilesClient\\Faction",
|
||||
"DBFilesClient\\FactionGroup",
|
||||
"DBFilesClient\\FactionTemplate",
|
||||
"DBFilesClient\\FileData",
|
||||
"DBFilesClient\\FileDataComplete",
|
||||
"DBFilesClient\\FootprintTextures",
|
||||
"DBFilesClient\\FootstepTerrainLookup",
|
||||
"DBFilesClient\\FriendshipRepReaction",
|
||||
"DBFilesClient\\FriendshipReputation",
|
||||
"DBFilesClient\\GMSurveyAnswers",
|
||||
"DBFilesClient\\GMSurveyCurrentSurvey",
|
||||
"DBFilesClient\\GMSurveyQuestions",
|
||||
"DBFilesClient\\GMSurveySurveys",
|
||||
"DBFilesClient\\GMTicketCategory",
|
||||
"DBFilesClient\\GameObjectArtKit",
|
||||
"DBFilesClient\\GameObjectDiffAnimMap",
|
||||
"DBFilesClient\\GameObjectDisplayInfo",
|
||||
"DBFilesClient\\GameObjects",
|
||||
"DBFilesClient\\GameTables",
|
||||
"DBFilesClient\\GameTips",
|
||||
"DBFilesClient\\GarrAbility",
|
||||
"DBFilesClient\\GarrAbilityCategory",
|
||||
"DBFilesClient\\GarrAbilityEffect",
|
||||
"DBFilesClient\\GarrBuilding",
|
||||
"DBFilesClient\\GarrBuildingDoodadSet",
|
||||
"DBFilesClient\\GarrBuildingPlotInst",
|
||||
"DBFilesClient\\GarrClassSpec",
|
||||
"DBFilesClient\\GarrEncounter",
|
||||
"DBFilesClient\\GarrEncounterXMechanic",
|
||||
"DBFilesClient\\GarrFollItemSet",
|
||||
"DBFilesClient\\GarrFollItemSetMember",
|
||||
"DBFilesClient\\GarrFollower",
|
||||
"DBFilesClient\\GarrFollowerLevelXP",
|
||||
"DBFilesClient\\GarrFollowerQuality",
|
||||
"DBFilesClient\\GarrFollowerType",
|
||||
"DBFilesClient\\GarrFollowerXAbility",
|
||||
"DBFilesClient\\GarrMechanic",
|
||||
"DBFilesClient\\GarrMechanicType",
|
||||
"DBFilesClient\\GarrMission",
|
||||
"DBFilesClient\\GarrMissionReward",
|
||||
"DBFilesClient\\GarrMissionTexture",
|
||||
"DBFilesClient\\GarrMissionType",
|
||||
"DBFilesClient\\GarrMissionXEncounter",
|
||||
"DBFilesClient\\GarrMssnBonusAbility",
|
||||
"DBFilesClient\\GarrPlot",
|
||||
"DBFilesClient\\GarrPlotBuilding",
|
||||
"DBFilesClient\\GarrPlotInstance",
|
||||
"DBFilesClient\\GarrPlotUICategory",
|
||||
"DBFilesClient\\GarrSiteLevel",
|
||||
"DBFilesClient\\GarrSiteLevelPlotInst",
|
||||
"DBFilesClient\\GarrSpecialization",
|
||||
"DBFilesClient\\GarrUiAnimClassInfo",
|
||||
"DBFilesClient\\GarrUiAnimRaceInfo",
|
||||
"DBFilesClient\\GemProperties",
|
||||
"DBFilesClient\\GlueScreenEmote",
|
||||
"DBFilesClient\\GlyphExclusiveCategory",
|
||||
"DBFilesClient\\GlyphProperties",
|
||||
"DBFilesClient\\GlyphRequiredSpec",
|
||||
"DBFilesClient\\GlyphSlot",
|
||||
"DBFilesClient\\GroundEffectDoodad",
|
||||
"DBFilesClient\\GroundEffectTexture",
|
||||
"DBFilesClient\\GroupFinderActivity",
|
||||
"DBFilesClient\\GroupFinderActivityGrp",
|
||||
"DBFilesClient\\GroupFinderCategory",
|
||||
"DBFilesClient\\GuildColorBackground",
|
||||
"DBFilesClient\\GuildColorBorder",
|
||||
"DBFilesClient\\GuildColorEmblem",
|
||||
"DBFilesClient\\GuildPerkSpells",
|
||||
"DBFilesClient\\Heirloom",
|
||||
"DBFilesClient\\HelmetAnimScaling",
|
||||
"DBFilesClient\\HelmetGeosetVisData",
|
||||
"DBFilesClient\\HighlightColor",
|
||||
"DBFilesClient\\HolidayDescriptions",
|
||||
"DBFilesClient\\HolidayNames",
|
||||
"DBFilesClient\\Holidays",
|
||||
"DBFilesClient\\ImportPriceArmor",
|
||||
"DBFilesClient\\ImportPriceQuality",
|
||||
"DBFilesClient\\ImportPriceShield",
|
||||
"DBFilesClient\\ImportPriceWeapon",
|
||||
"DBFilesClient\\Item-sparse",
|
||||
"DBFilesClient\\Item",
|
||||
"DBFilesClient\\ItemAppearance",
|
||||
"DBFilesClient\\ItemArmorQuality",
|
||||
"DBFilesClient\\ItemArmorShield",
|
||||
"DBFilesClient\\ItemArmorTotal",
|
||||
"DBFilesClient\\ItemBagFamily",
|
||||
"DBFilesClient\\ItemBonus",
|
||||
"DBFilesClient\\ItemBonusTreeNode",
|
||||
"DBFilesClient\\ItemClass",
|
||||
"DBFilesClient\\ItemCurrencyCost",
|
||||
"DBFilesClient\\ItemDamageAmmo",
|
||||
"DBFilesClient\\ItemDamageOneHand",
|
||||
"DBFilesClient\\ItemDamageOneHandCaster",
|
||||
"DBFilesClient\\ItemDamageRanged",
|
||||
"DBFilesClient\\ItemDamageThrown",
|
||||
"DBFilesClient\\ItemDamageTwoHand",
|
||||
"DBFilesClient\\ItemDamageTwoHandCaster",
|
||||
"DBFilesClient\\ItemDamageWand",
|
||||
"DBFilesClient\\ItemDisenchantLoot",
|
||||
"DBFilesClient\\ItemDisplayInfo",
|
||||
"DBFilesClient\\ItemEffect",
|
||||
"DBFilesClient\\ItemExtendedCost",
|
||||
"DBFilesClient\\ItemGroupSounds",
|
||||
"DBFilesClient\\ItemLimitCategory",
|
||||
"DBFilesClient\\ItemModifiedAppearance",
|
||||
"DBFilesClient\\ItemNameDescription",
|
||||
"DBFilesClient\\ItemPetFood",
|
||||
"DBFilesClient\\ItemPriceBase",
|
||||
"DBFilesClient\\ItemPurchaseGroup",
|
||||
"DBFilesClient\\ItemRandomProperties",
|
||||
"DBFilesClient\\ItemRandomSuffix",
|
||||
"DBFilesClient\\ItemSet",
|
||||
"DBFilesClient\\ItemSetSpell",
|
||||
"DBFilesClient\\ItemSpec",
|
||||
"DBFilesClient\\ItemSpecOverride",
|
||||
"DBFilesClient\\ItemSubClass",
|
||||
"DBFilesClient\\ItemSubClassMask",
|
||||
"DBFilesClient\\ItemToBattlePetSpecies",
|
||||
"DBFilesClient\\ItemToMountSpell",
|
||||
"DBFilesClient\\ItemUpgrade",
|
||||
"DBFilesClient\\ItemUpgradePath",
|
||||
"DBFilesClient\\ItemVisualEffects",
|
||||
"DBFilesClient\\ItemVisuals",
|
||||
"DBFilesClient\\ItemXBonusTree",
|
||||
"DBFilesClient\\JournalEncounter",
|
||||
"DBFilesClient\\JournalEncounterCreature",
|
||||
"DBFilesClient\\JournalEncounterItem",
|
||||
"DBFilesClient\\JournalEncounterSection",
|
||||
"DBFilesClient\\JournalEncounterXDifficulty",
|
||||
"DBFilesClient\\JournalInstance",
|
||||
"DBFilesClient\\JournalItemXDifficulty",
|
||||
"DBFilesClient\\JournalSectionXDifficulty",
|
||||
"DBFilesClient\\JournalTier",
|
||||
"DBFilesClient\\JournalTierXInstance",
|
||||
"DBFilesClient\\KeyChain",
|
||||
"DBFilesClient\\LanguageWords",
|
||||
"DBFilesClient\\Languages",
|
||||
"DBFilesClient\\LfgDungeonExpansion",
|
||||
"DBFilesClient\\LfgDungeonGroup",
|
||||
"DBFilesClient\\LfgDungeons",
|
||||
"DBFilesClient\\LfgDungeonsGroupingMap",
|
||||
"DBFilesClient\\LfgRoleRequirement",
|
||||
"DBFilesClient\\Light",
|
||||
"DBFilesClient\\LightData",
|
||||
"DBFilesClient\\LightParams",
|
||||
"DBFilesClient\\LightSkybox",
|
||||
"DBFilesClient\\LiquidMaterial",
|
||||
"DBFilesClient\\LiquidObject",
|
||||
"DBFilesClient\\LiquidType",
|
||||
"DBFilesClient\\LoadingScreenTaxiSplines",
|
||||
"DBFilesClient\\LoadingScreens",
|
||||
"DBFilesClient\\Locale",
|
||||
"DBFilesClient\\Location",
|
||||
"DBFilesClient\\Lock",
|
||||
"DBFilesClient\\LockType",
|
||||
"DBFilesClient\\LookAtController",
|
||||
"DBFilesClient\\MailTemplate",
|
||||
"DBFilesClient\\ManifestInterfaceActionIcon",
|
||||
"DBFilesClient\\ManifestInterfaceData",
|
||||
"DBFilesClient\\ManifestInterfaceItemIcon",
|
||||
"DBFilesClient\\ManifestInterfaceTOCData",
|
||||
"DBFilesClient\\ManifestMP3",
|
||||
"DBFilesClient\\Map",
|
||||
"DBFilesClient\\MapChallengeMode",
|
||||
"DBFilesClient\\MapDifficulty",
|
||||
"DBFilesClient\\MarketingPromotionsXLocale",
|
||||
"DBFilesClient\\Material",
|
||||
"DBFilesClient\\MinorTalent",
|
||||
"DBFilesClient\\ModelFileData",
|
||||
"DBFilesClient\\ModelManifest",
|
||||
"DBFilesClient\\ModelNameToManifest",
|
||||
"DBFilesClient\\ModifierTree",
|
||||
"DBFilesClient\\Mount",
|
||||
"DBFilesClient\\MountCapability",
|
||||
"DBFilesClient\\MountType",
|
||||
"DBFilesClient\\MountTypeXCapability",
|
||||
"DBFilesClient\\Movie",
|
||||
"DBFilesClient\\MovieFileData",
|
||||
"DBFilesClient\\MovieOverlays",
|
||||
"DBFilesClient\\MovieVariation",
|
||||
"DBFilesClient\\NPCSounds",
|
||||
"DBFilesClient\\NameGen",
|
||||
"DBFilesClient\\NamesProfanity",
|
||||
"DBFilesClient\\NamesReserved",
|
||||
"DBFilesClient\\NamesReservedLocale",
|
||||
"DBFilesClient\\ObjectEffect",
|
||||
"DBFilesClient\\ObjectEffectGroup",
|
||||
"DBFilesClient\\ObjectEffectModifier",
|
||||
"DBFilesClient\\ObjectEffectPackage",
|
||||
"DBFilesClient\\ObjectEffectPackageElem",
|
||||
"DBFilesClient\\OverrideSpellData",
|
||||
"DBFilesClient\\PageTextMaterial",
|
||||
"DBFilesClient\\PaperDollItemFrame",
|
||||
"DBFilesClient\\ParticleColor",
|
||||
"DBFilesClient\\Path",
|
||||
"DBFilesClient\\PathNode",
|
||||
"DBFilesClient\\PathNodeProperty",
|
||||
"DBFilesClient\\PathProperty",
|
||||
"DBFilesClient\\Phase",
|
||||
"DBFilesClient\\PhaseShiftZoneSounds",
|
||||
"DBFilesClient\\PhaseXPhaseGroup",
|
||||
"DBFilesClient\\PlayerCondition",
|
||||
"DBFilesClient\\PowerDisplay",
|
||||
"DBFilesClient\\PvpDifficulty",
|
||||
"DBFilesClient\\PvpItem",
|
||||
"DBFilesClient\\QuestFactionReward",
|
||||
"DBFilesClient\\QuestFeedbackEffect",
|
||||
"DBFilesClient\\QuestInfo",
|
||||
"DBFilesClient\\QuestLine",
|
||||
"DBFilesClient\\QuestLineXQuest",
|
||||
"DBFilesClient\\QuestMoneyReward",
|
||||
"DBFilesClient\\QuestObjectiveCliTask",
|
||||
"DBFilesClient\\QuestPOIBlob",
|
||||
"DBFilesClient\\QuestPOIPoint",
|
||||
"DBFilesClient\\QuestPOIPointCliTask",
|
||||
"DBFilesClient\\QuestPackageItem",
|
||||
"DBFilesClient\\QuestSort",
|
||||
"DBFilesClient\\QuestV2",
|
||||
"DBFilesClient\\QuestV2CliTask",
|
||||
"DBFilesClient\\QuestXP",
|
||||
"DBFilesClient\\RacialMounts",
|
||||
"DBFilesClient\\RandPropPoints",
|
||||
"DBFilesClient\\ResearchBranch",
|
||||
"DBFilesClient\\ResearchField",
|
||||
"DBFilesClient\\ResearchProject",
|
||||
"DBFilesClient\\ResearchSite",
|
||||
"DBFilesClient\\Resistances",
|
||||
"DBFilesClient\\RulesetItemUpgrade",
|
||||
"DBFilesClient\\RulesetRaidLootUpgrade",
|
||||
"DBFilesClient\\RulesetRaidOverride",
|
||||
"DBFilesClient\\ScalingStatDistribution",
|
||||
"DBFilesClient\\Scenario",
|
||||
"DBFilesClient\\ScenarioEventEntry",
|
||||
"DBFilesClient\\ScenarioStep",
|
||||
"DBFilesClient\\SceneScript",
|
||||
"DBFilesClient\\SceneScriptPackage",
|
||||
"DBFilesClient\\SceneScriptPackageMember",
|
||||
"DBFilesClient\\ScreenEffect",
|
||||
"DBFilesClient\\ScreenLocation",
|
||||
"DBFilesClient\\ServerMessages",
|
||||
"DBFilesClient\\SkillLine",
|
||||
"DBFilesClient\\SkillLineAbility",
|
||||
"DBFilesClient\\SkillLineAbilitySortedSpell",
|
||||
"DBFilesClient\\SkillRaceClassInfo",
|
||||
"DBFilesClient\\SoundAmbience",
|
||||
"DBFilesClient\\SoundAmbienceFlavor",
|
||||
"DBFilesClient\\SoundBus",
|
||||
"DBFilesClient\\SoundBusName",
|
||||
"DBFilesClient\\SoundEmitterPillPoints",
|
||||
"DBFilesClient\\SoundEmitters",
|
||||
"DBFilesClient\\SoundEntries",
|
||||
"DBFilesClient\\SoundEntriesAdvanced",
|
||||
"DBFilesClient\\SoundEntriesFallbacks",
|
||||
"DBFilesClient\\SoundFilter",
|
||||
"DBFilesClient\\SoundFilterElem",
|
||||
"DBFilesClient\\SoundOverride",
|
||||
"DBFilesClient\\SoundProviderPreferences",
|
||||
"DBFilesClient\\SpamMessages",
|
||||
"DBFilesClient\\SpecializationSpells",
|
||||
"DBFilesClient\\Spell",
|
||||
"DBFilesClient\\SpellActionBarPref",
|
||||
"DBFilesClient\\SpellActivationOverlay",
|
||||
"DBFilesClient\\SpellAuraOptions",
|
||||
"DBFilesClient\\SpellAuraRestrictions",
|
||||
"DBFilesClient\\SpellAuraRestrictionsDifficulty",
|
||||
"DBFilesClient\\SpellAuraVisXChrSpec",
|
||||
"DBFilesClient\\SpellAuraVisibility",
|
||||
"DBFilesClient\\SpellCastTimes",
|
||||
"DBFilesClient\\SpellCastingRequirements",
|
||||
"DBFilesClient\\SpellCategories",
|
||||
"DBFilesClient\\SpellCategory",
|
||||
"DBFilesClient\\SpellChainEffects",
|
||||
"DBFilesClient\\SpellClassOptions",
|
||||
"DBFilesClient\\SpellCooldowns",
|
||||
"DBFilesClient\\SpellDescriptionVariables",
|
||||
"DBFilesClient\\SpellDispelType",
|
||||
"DBFilesClient\\SpellDuration",
|
||||
"DBFilesClient\\SpellEffect",
|
||||
"DBFilesClient\\SpellEffectCameraShakes",
|
||||
"DBFilesClient\\SpellEffectGroupSize",
|
||||
"DBFilesClient\\SpellEffectScaling",
|
||||
"DBFilesClient\\SpellEquippedItems",
|
||||
"DBFilesClient\\SpellFlyout",
|
||||
"DBFilesClient\\SpellFlyoutItem",
|
||||
"DBFilesClient\\SpellFocusObject",
|
||||
"DBFilesClient\\SpellIcon",
|
||||
"DBFilesClient\\SpellInterrupts",
|
||||
"DBFilesClient\\SpellItemEnchantment",
|
||||
"DBFilesClient\\SpellItemEnchantmentCondition",
|
||||
"DBFilesClient\\SpellKeyboundOverride",
|
||||
"DBFilesClient\\SpellLearnSpell",
|
||||
"DBFilesClient\\SpellLevels",
|
||||
"DBFilesClient\\SpellMechanic",
|
||||
"DBFilesClient\\SpellMisc",
|
||||
"DBFilesClient\\SpellMiscDifficulty",
|
||||
"DBFilesClient\\SpellMissile",
|
||||
"DBFilesClient\\SpellMissileMotion",
|
||||
"DBFilesClient\\SpellPower",
|
||||
"DBFilesClient\\SpellPowerDifficulty",
|
||||
"DBFilesClient\\SpellProcsPerMinute",
|
||||
"DBFilesClient\\SpellProcsPerMinuteMod",
|
||||
"DBFilesClient\\SpellRadius",
|
||||
"DBFilesClient\\SpellRange",
|
||||
"DBFilesClient\\SpellReagents",
|
||||
"DBFilesClient\\SpellReagentsCurrency",
|
||||
"DBFilesClient\\SpellRuneCost",
|
||||
"DBFilesClient\\SpellScaling",
|
||||
"DBFilesClient\\SpellShapeshift",
|
||||
"DBFilesClient\\SpellShapeshiftForm",
|
||||
"DBFilesClient\\SpellSpecialUnitEffect",
|
||||
"DBFilesClient\\SpellTargetRestrictions",
|
||||
"DBFilesClient\\SpellTotems",
|
||||
"DBFilesClient\\SpellVisual",
|
||||
"DBFilesClient\\SpellVisualColorEffect",
|
||||
"DBFilesClient\\SpellVisualEffectName",
|
||||
"DBFilesClient\\SpellVisualKit",
|
||||
"DBFilesClient\\SpellVisualKitAreaModel",
|
||||
"DBFilesClient\\SpellVisualKitModelAttach",
|
||||
"DBFilesClient\\SpellVisualMissile",
|
||||
"DBFilesClient\\SpellXSpellVisual",
|
||||
"DBFilesClient\\Startup_Strings",
|
||||
"DBFilesClient\\Stationery",
|
||||
"DBFilesClient\\StringLookups",
|
||||
"DBFilesClient\\SummonProperties",
|
||||
"DBFilesClient\\Talent",
|
||||
"DBFilesClient\\TaxiNodes",
|
||||
"DBFilesClient\\TaxiPath",
|
||||
"DBFilesClient\\TaxiPathNode",
|
||||
"DBFilesClient\\TerrainMaterial",
|
||||
"DBFilesClient\\TerrainType",
|
||||
"DBFilesClient\\TerrainTypeSounds",
|
||||
"DBFilesClient\\TextureFileData",
|
||||
"DBFilesClient\\TotemCategory",
|
||||
"DBFilesClient\\Toy",
|
||||
"DBFilesClient\\TradeSkillCategory",
|
||||
"DBFilesClient\\TransportAnimation",
|
||||
"DBFilesClient\\TransportPhysics",
|
||||
"DBFilesClient\\TransportRotation",
|
||||
"DBFilesClient\\Trophy",
|
||||
"DBFilesClient\\TrophyInstance",
|
||||
"DBFilesClient\\TrophyType",
|
||||
"DBFilesClient\\UiTextureAtlas",
|
||||
"DBFilesClient\\UiTextureAtlasMember",
|
||||
"DBFilesClient\\UiTextureKit",
|
||||
"DBFilesClient\\UnitBlood",
|
||||
"DBFilesClient\\UnitBloodLevels",
|
||||
"DBFilesClient\\UnitCondition",
|
||||
"DBFilesClient\\UnitPowerBar",
|
||||
"DBFilesClient\\Vehicle",
|
||||
"DBFilesClient\\VehicleSeat",
|
||||
"DBFilesClient\\VehicleUIIndSeat",
|
||||
"DBFilesClient\\VehicleUIIndicator",
|
||||
"DBFilesClient\\VideoHardware",
|
||||
"DBFilesClient\\Vignette",
|
||||
"DBFilesClient\\VocalUISounds",
|
||||
"DBFilesClient\\WMOAreaTable",
|
||||
"DBFilesClient\\WbAccessControlList",
|
||||
"DBFilesClient\\WbCertBlacklist",
|
||||
"DBFilesClient\\WbCertWhitelist",
|
||||
"DBFilesClient\\WbPermissions",
|
||||
"DBFilesClient\\WeaponImpactSounds",
|
||||
"DBFilesClient\\WeaponSwingSounds2",
|
||||
"DBFilesClient\\WeaponTrail",
|
||||
"DBFilesClient\\Weather",
|
||||
"DBFilesClient\\WindSettings",
|
||||
"DBFilesClient\\WorldBossLockout",
|
||||
"DBFilesClient\\WorldChunkSounds",
|
||||
"DBFilesClient\\WorldEffect",
|
||||
"DBFilesClient\\WorldElapsedTimer",
|
||||
"DBFilesClient\\WorldMapArea",
|
||||
"DBFilesClient\\WorldMapContinent",
|
||||
"DBFilesClient\\WorldMapOverlay",
|
||||
"DBFilesClient\\WorldMapTransforms",
|
||||
"DBFilesClient\\WorldSafeLocs",
|
||||
"DBFilesClient\\WorldState",
|
||||
"DBFilesClient\\WorldStateExpression",
|
||||
"DBFilesClient\\WorldStateUI",
|
||||
"DBFilesClient\\WorldStateZoneSounds",
|
||||
"DBFilesClient\\World_PVP_Area",
|
||||
"DBFilesClient\\ZoneIntroMusicTable",
|
||||
"DBFilesClient\\ZoneLight",
|
||||
"DBFilesClient\\ZoneLightPoint",
|
||||
"DBFilesClient\\ZoneMusic",
|
||||
"DBFilesClient\\gtArmorMitigationByLvl",
|
||||
"DBFilesClient\\gtAttackPower",
|
||||
"DBFilesClient\\gtAttackPowerRanged",
|
||||
"DBFilesClient\\gtAvoidanceDim",
|
||||
"DBFilesClient\\gtBarberShopCostBase",
|
||||
"DBFilesClient\\gtBattlePetTypeDamageMod",
|
||||
"DBFilesClient\\gtBattlePetXP",
|
||||
"DBFilesClient\\gtChanceToDodgeBase",
|
||||
"DBFilesClient\\gtChanceToMeleeCrit",
|
||||
"DBFilesClient\\gtChanceToMeleeCritBase",
|
||||
"DBFilesClient\\gtChanceToParryBase",
|
||||
"DBFilesClient\\gtChanceToSpellCrit",
|
||||
"DBFilesClient\\gtChanceToSpellCritBase",
|
||||
"DBFilesClient\\gtCombatRatings",
|
||||
"DBFilesClient\\gtItemLevelByLevel",
|
||||
"DBFilesClient\\gtItemSocketCostPerLevel",
|
||||
"DBFilesClient\\gtNPCExpectedResistPhysExp1",
|
||||
"DBFilesClient\\gtNPCExpectedResistPhysExp2",
|
||||
"DBFilesClient\\gtNPCExpectedResistPhysExp3",
|
||||
"DBFilesClient\\gtNPCExpectedResistPhysExp4",
|
||||
"DBFilesClient\\gtNPCExpectedResistPhysExp5",
|
||||
"DBFilesClient\\gtNPCManaCostScaler",
|
||||
"DBFilesClient\\gtNpcDamageByClass",
|
||||
"DBFilesClient\\gtNpcDamageByClassExp1",
|
||||
"DBFilesClient\\gtNpcDamageByClassExp2",
|
||||
"DBFilesClient\\gtNpcDamageByClassExp3",
|
||||
"DBFilesClient\\gtNpcDamageByClassExp4",
|
||||
"DBFilesClient\\gtNpcDamageByClassExp5",
|
||||
"DBFilesClient\\gtNpcGuildExperience",
|
||||
"DBFilesClient\\gtNpcTotalHp",
|
||||
"DBFilesClient\\gtNpcTotalHpExp1",
|
||||
"DBFilesClient\\gtNpcTotalHpExp2",
|
||||
"DBFilesClient\\gtNpcTotalHpExp3",
|
||||
"DBFilesClient\\gtNpcTotalHpExp4",
|
||||
"DBFilesClient\\gtNpcTotalHpExp5",
|
||||
"DBFilesClient\\gtNpcTotalMp",
|
||||
"DBFilesClient\\gtOCTBaseHPByClass",
|
||||
"DBFilesClient\\gtOCTBaseMPByClass",
|
||||
"DBFilesClient\\gtOCTChanceToDodge",
|
||||
"DBFilesClient\\gtOCTChanceToParry",
|
||||
"DBFilesClient\\gtOCTClassCombatRatingScalar",
|
||||
"DBFilesClient\\gtOCTClassStats",
|
||||
"DBFilesClient\\gtOCTHPFromItems",
|
||||
"DBFilesClient\\gtOCTHpPerStamina",
|
||||
"DBFilesClient\\gtOCTLevelExperience",
|
||||
"DBFilesClient\\gtOCTMPFromItems",
|
||||
"DBFilesClient\\gtOCTMPPerIntellect",
|
||||
"DBFilesClient\\gtOCTNPCDpsScaler",
|
||||
"DBFilesClient\\gtOCTNPCExpectedAgility",
|
||||
"DBFilesClient\\gtOCTNPCExpectedIntellect",
|
||||
"DBFilesClient\\gtOCTNPCExpectedResistPhysical",
|
||||
"DBFilesClient\\gtOCTNPCExpectedSpirit",
|
||||
"DBFilesClient\\gtOCTNPCExpectedStamina",
|
||||
"DBFilesClient\\gtOCTNPCExpectedStrength",
|
||||
"DBFilesClient\\gtOCTNPCHPScaler",
|
||||
"DBFilesClient\\gtOCTRaceStats",
|
||||
"DBFilesClient\\gtPCBaseAgility",
|
||||
"DBFilesClient\\gtPCBaseIntellect",
|
||||
"DBFilesClient\\gtPCBaseSpirit",
|
||||
"DBFilesClient\\gtPCBaseStamina",
|
||||
"DBFilesClient\\gtPCBaseStrength",
|
||||
"DBFilesClient\\gtPCExpectedAgility",
|
||||
"DBFilesClient\\gtPCExpectedIntellect",
|
||||
"DBFilesClient\\gtPCExpectedSpirit",
|
||||
"DBFilesClient\\gtPCExpectedStamina",
|
||||
"DBFilesClient\\gtPCExpectedStrength",
|
||||
"DBFilesClient\\gtPVPRanks",
|
||||
"DBFilesClient\\gtRageGenScaler",
|
||||
"DBFilesClient\\gtRegenMPPerSpt",
|
||||
"DBFilesClient\\gtResilienceDR",
|
||||
"DBFilesClient\\gtResistanceInnateFire",
|
||||
"DBFilesClient\\gtResistanceInnateFrost",
|
||||
"DBFilesClient\\gtResistanceInnateHoly",
|
||||
"DBFilesClient\\gtResistanceInnateNature",
|
||||
"DBFilesClient\\gtResistanceInnateShadow",
|
||||
"DBFilesClient\\gtShieldBlockRegular",
|
||||
"DBFilesClient\\gtSpellScaling",
|
||||
"DBFilesClient\\gtXPGroupBonus",
|
||||
nullptr // terminator
|
||||
};
|
||||
|
||||
#endif // DBFilesClientList_h__
|
||||
102
src/tools/map_extractor/loadlib/loadlib.h
Normal file
102
src/tools/map_extractor/loadlib/loadlib.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef LOAD_LIB_H
|
||||
#define LOAD_LIB_H
|
||||
|
||||
#include "Define.h"
|
||||
#ifdef TC_PLATFORM_WINDOWS
|
||||
#undef TC_PLATFORM_WINDOWS
|
||||
#endif
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#ifndef _WIN32
|
||||
int GetLastError();
|
||||
#endif
|
||||
|
||||
#define FILE_FORMAT_VERSION 18
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
union u_map_fcc
|
||||
{
|
||||
char fcc_txt[4];
|
||||
uint32 fcc;
|
||||
};
|
||||
|
||||
//
|
||||
// File version chunk
|
||||
//
|
||||
struct file_MVER
|
||||
{
|
||||
union{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
uint32 size;
|
||||
uint32 ver;
|
||||
};
|
||||
|
||||
struct file_MWMO
|
||||
{
|
||||
u_map_fcc fcc;
|
||||
uint32 size;
|
||||
char FileList[1];
|
||||
};
|
||||
|
||||
class FileChunk
|
||||
{
|
||||
public:
|
||||
FileChunk(uint8* data_, uint32 size_) : data(data_), size(size_) { }
|
||||
~FileChunk();
|
||||
|
||||
uint8* data;
|
||||
uint32 size;
|
||||
|
||||
template<class T>
|
||||
T* As() { return (T*)data; }
|
||||
void parseSubChunks();
|
||||
std::multimap<std::string, FileChunk*> subchunks;
|
||||
FileChunk* GetSubChunk(std::string const& name);
|
||||
};
|
||||
|
||||
class ChunkedFile
|
||||
{
|
||||
public:
|
||||
uint8 *data;
|
||||
uint32 data_size;
|
||||
|
||||
uint8 *GetData() { return data; }
|
||||
uint32 GetDataSize() { return data_size; }
|
||||
|
||||
ChunkedFile();
|
||||
virtual ~ChunkedFile();
|
||||
bool prepareLoadedData();
|
||||
bool loadFile(std::string const& fileName, bool log = true);
|
||||
void free();
|
||||
|
||||
void parseChunks();
|
||||
std::multimap<std::string, FileChunk*> chunks;
|
||||
FileChunk* GetChunk(std::string const& name);
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
50
src/tools/map_extractor/wdt.h
Normal file
50
src/tools/map_extractor/wdt.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef WDT_H
|
||||
#define WDT_H
|
||||
#include "loadlib.h"
|
||||
|
||||
//**************************************************************************************
|
||||
// WDT file class and structures
|
||||
//**************************************************************************************
|
||||
#define WDT_MAP_SIZE 64
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
|
||||
class wdt_MAIN
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32 fcc;
|
||||
char fcc_txt[4];
|
||||
};
|
||||
public:
|
||||
uint32 size;
|
||||
|
||||
struct adtData
|
||||
{
|
||||
uint32 flag;
|
||||
uint32 data1;
|
||||
} adt_list[64][64];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
78
src/tools/mmaps_generator/CMakeLists.txt
Normal file
78
src/tools/mmaps_generator/CMakeLists.txt
Normal file
@@ -0,0 +1,78 @@
|
||||
# Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
file(GLOB_RECURSE mmap_gen_sources *.cpp *.h)
|
||||
|
||||
set(mmap_gen_Includes
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/zmqpp
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
${CMAKE_SOURCE_DIR}/dep/libmpq
|
||||
${CMAKE_SOURCE_DIR}/dep/zlib
|
||||
${CMAKE_SOURCE_DIR}/dep/bzip2
|
||||
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast/Include
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
|
||||
${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography/Authentication
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Database
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Database/Implementation
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Logging
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Networking
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
|
||||
${CMAKE_SOURCE_DIR}/src/server/game/Conditions
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision/Management
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision/Maps
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision/Models
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
${VALGRIND_INCLUDE_DIR}
|
||||
${ZMQ_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if( WIN32 )
|
||||
set(mmap_gen_Includes
|
||||
${mmap_gen_Includes}
|
||||
${CMAKE_SOURCE_DIR}/dep/libmpq/win
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(${mmap_gen_Includes})
|
||||
|
||||
add_executable(mmaps_generator ${mmap_gen_sources})
|
||||
|
||||
target_link_libraries(mmaps_generator
|
||||
g3dlib
|
||||
Recast
|
||||
Detour
|
||||
shared
|
||||
${MYSQL_LIBRARY}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${Boost_LIBRARIES}
|
||||
)
|
||||
|
||||
if( UNIX )
|
||||
install(TARGETS mmaps_generator DESTINATION bin)
|
||||
elseif( WIN32 )
|
||||
install(TARGETS mmaps_generator DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
69
src/tools/mmaps_generator/Info/readme.txt
Normal file
69
src/tools/mmaps_generator/Info/readme.txt
Normal file
@@ -0,0 +1,69 @@
|
||||
Generator command line args
|
||||
|
||||
--threads [#] Max number of threads used by the generator
|
||||
Default: 3
|
||||
|
||||
--offMeshInput [file.*] Path to file containing off mesh connections data.
|
||||
Format must be: (see offmesh_example.txt)
|
||||
"map_id tile_x,tile_y (start_x start_y start_z) (end_x end_y end_z) size //optional comments"
|
||||
Single mesh connection per line.
|
||||
|
||||
--silent [] Make us script friendly. Do not wait for user input
|
||||
on error or completion.
|
||||
|
||||
--bigBaseUnit [true|false] Generate tile/map using bigger basic unit.
|
||||
Use this option only if you have unexpected gaps.
|
||||
|
||||
false: use normal metrics (default)
|
||||
|
||||
--maxAngle [#] Max walkable inclination angle
|
||||
|
||||
float between 45 and 90 degrees (default 60)
|
||||
|
||||
--skipLiquid [true|false] extract liquid data for maps
|
||||
|
||||
false: include liquid data (default)
|
||||
|
||||
--skipContinents [true|false] continents are maps 0 (Eastern Kingdoms),
|
||||
1 (Kalimdor), 530 (Outlands), 571 (Northrend)
|
||||
|
||||
false: build continents (default)
|
||||
|
||||
--skipJunkMaps [true|false] junk maps include some unused
|
||||
maps, transport maps, and some other
|
||||
|
||||
true: skip junk maps (default)
|
||||
|
||||
--skipBattlegrounds [true|false] does not include PVP arenas
|
||||
|
||||
false: skip battlegrounds (default)
|
||||
|
||||
--debugOutput [true|false] create debugging files for use with RecastDemo
|
||||
if you are only creating mmaps for use with MaNGOS,
|
||||
you don't want debugging files
|
||||
|
||||
false: don't create debugging files (default)
|
||||
|
||||
--tile [#,#] Build the specified tile
|
||||
seperate number with a comma ','
|
||||
must specify a map number (see below)
|
||||
if this option is not used, all tiles are built
|
||||
|
||||
[#] Build only the map specified by #
|
||||
this command will build the map regardless of --skip* option settings
|
||||
if you do not specify a map number, builds all maps that pass the filters specified by --skip* options
|
||||
|
||||
|
||||
examples:
|
||||
|
||||
movement_extractor
|
||||
builds maps using the default settings (see above for defaults)
|
||||
|
||||
movement_extractor --skipContinents true
|
||||
builds the default maps, except continents
|
||||
|
||||
movement_extractor 0
|
||||
builds all tiles of map 0
|
||||
|
||||
movement_extractor 0 --tile 34,46
|
||||
builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain)
|
||||
277
src/tools/mmaps_generator/IntermediateValues.cpp
Normal file
277
src/tools/mmaps_generator/IntermediateValues.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "IntermediateValues.h"
|
||||
|
||||
namespace MMAP
|
||||
{
|
||||
IntermediateValues::~IntermediateValues()
|
||||
{
|
||||
rcFreeCompactHeightfield(compactHeightfield);
|
||||
rcFreeHeightField(heightfield);
|
||||
rcFreeContourSet(contours);
|
||||
rcFreePolyMesh(polyMesh);
|
||||
rcFreePolyMeshDetail(polyMeshDetail);
|
||||
}
|
||||
|
||||
void IntermediateValues::writeIV(uint32 mapID, uint32 tileX, uint32 tileY)
|
||||
{
|
||||
char fileName[255];
|
||||
char tileString[25];
|
||||
sprintf(tileString, "[%02u,%02u]: ", tileX, tileY);
|
||||
|
||||
printf("%sWriting debug output... \r", tileString);
|
||||
|
||||
std::string name("meshes/%04u%02i%02i.");
|
||||
|
||||
#define DEBUG_WRITE(fileExtension,data) \
|
||||
do { \
|
||||
sprintf(fileName, (name + fileExtension).c_str(), mapID, tileY, tileX); \
|
||||
FILE* file = fopen(fileName, "wb"); \
|
||||
if (!file) \
|
||||
{ \
|
||||
char message[1024]; \
|
||||
sprintf(message, "%sFailed to open %s for writing!\n", tileString, fileName); \
|
||||
perror(message); \
|
||||
} \
|
||||
else \
|
||||
debugWrite(file, data); \
|
||||
if (file) fclose(file); \
|
||||
printf("%sWriting debug output... \r", tileString); \
|
||||
} while (false)
|
||||
|
||||
if (heightfield)
|
||||
DEBUG_WRITE("hf", heightfield);
|
||||
if (compactHeightfield)
|
||||
DEBUG_WRITE("chf", compactHeightfield);
|
||||
if (contours)
|
||||
DEBUG_WRITE("cs", contours);
|
||||
if (polyMesh)
|
||||
DEBUG_WRITE("pmesh", polyMesh);
|
||||
if (polyMeshDetail)
|
||||
DEBUG_WRITE("dmesh", polyMeshDetail);
|
||||
|
||||
#undef DEBUG_WRITE
|
||||
}
|
||||
|
||||
void IntermediateValues::debugWrite(FILE* file, const rcHeightfield* mesh)
|
||||
{
|
||||
if (!file || !mesh)
|
||||
return;
|
||||
|
||||
fwrite(&(mesh->cs), sizeof(float), 1, file);
|
||||
fwrite(&(mesh->ch), sizeof(float), 1, file);
|
||||
fwrite(&(mesh->width), sizeof(int), 1, file);
|
||||
fwrite(&(mesh->height), sizeof(int), 1, file);
|
||||
fwrite(mesh->bmin, sizeof(float), 3, file);
|
||||
fwrite(mesh->bmax, sizeof(float), 3, file);
|
||||
|
||||
for (int y = 0; y < mesh->height; ++y)
|
||||
for (int x = 0; x < mesh->width; ++x)
|
||||
{
|
||||
rcSpan* span = mesh->spans[x+y*mesh->width];
|
||||
|
||||
// first, count the number of spans
|
||||
int spanCount = 0;
|
||||
while (span)
|
||||
{
|
||||
spanCount++;
|
||||
span = span->next;
|
||||
}
|
||||
|
||||
// write the span count
|
||||
fwrite(&spanCount, sizeof(int), 1, file);
|
||||
|
||||
// write the spans
|
||||
span = mesh->spans[x+y*mesh->width];
|
||||
while (span)
|
||||
{
|
||||
fwrite(span, sizeof(rcSpan), 1, file);
|
||||
span = span->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateValues::debugWrite(FILE* file, const rcCompactHeightfield* chf)
|
||||
{
|
||||
if (!file | !chf)
|
||||
return;
|
||||
|
||||
fwrite(&(chf->width), sizeof(chf->width), 1, file);
|
||||
fwrite(&(chf->height), sizeof(chf->height), 1, file);
|
||||
fwrite(&(chf->spanCount), sizeof(chf->spanCount), 1, file);
|
||||
|
||||
fwrite(&(chf->walkableHeight), sizeof(chf->walkableHeight), 1, file);
|
||||
fwrite(&(chf->walkableClimb), sizeof(chf->walkableClimb), 1, file);
|
||||
|
||||
fwrite(&(chf->maxDistance), sizeof(chf->maxDistance), 1, file);
|
||||
fwrite(&(chf->maxRegions), sizeof(chf->maxRegions), 1, file);
|
||||
|
||||
fwrite(chf->bmin, sizeof(chf->bmin), 1, file);
|
||||
fwrite(chf->bmax, sizeof(chf->bmax), 1, file);
|
||||
|
||||
fwrite(&(chf->cs), sizeof(chf->cs), 1, file);
|
||||
fwrite(&(chf->ch), sizeof(chf->ch), 1, file);
|
||||
|
||||
int tmp = 0;
|
||||
if (chf->cells) tmp |= 1;
|
||||
if (chf->spans) tmp |= 2;
|
||||
if (chf->dist) tmp |= 4;
|
||||
if (chf->areas) tmp |= 8;
|
||||
|
||||
fwrite(&tmp, sizeof(tmp), 1, file);
|
||||
|
||||
if (chf->cells)
|
||||
fwrite(chf->cells, sizeof(rcCompactCell), chf->width*chf->height, file);
|
||||
if (chf->spans)
|
||||
fwrite(chf->spans, sizeof(rcCompactSpan), chf->spanCount, file);
|
||||
if (chf->dist)
|
||||
fwrite(chf->dist, sizeof(unsigned short), chf->spanCount, file);
|
||||
if (chf->areas)
|
||||
fwrite(chf->areas, sizeof(unsigned char), chf->spanCount, file);
|
||||
}
|
||||
|
||||
void IntermediateValues::debugWrite(FILE* file, const rcContourSet* cs)
|
||||
{
|
||||
if (!file || !cs)
|
||||
return;
|
||||
|
||||
fwrite(&(cs->cs), sizeof(float), 1, file);
|
||||
fwrite(&(cs->ch), sizeof(float), 1, file);
|
||||
fwrite(cs->bmin, sizeof(float), 3, file);
|
||||
fwrite(cs->bmax, sizeof(float), 3, file);
|
||||
fwrite(&(cs->nconts), sizeof(int), 1, file);
|
||||
for (int i = 0; i < cs->nconts; ++i)
|
||||
{
|
||||
fwrite(&cs->conts[i].area, sizeof(unsigned char), 1, file);
|
||||
fwrite(&cs->conts[i].reg, sizeof(unsigned short), 1, file);
|
||||
fwrite(&cs->conts[i].nverts, sizeof(int), 1, file);
|
||||
fwrite(cs->conts[i].verts, sizeof(int), cs->conts[i].nverts*4, file);
|
||||
fwrite(&cs->conts[i].nrverts, sizeof(int), 1, file);
|
||||
fwrite(cs->conts[i].rverts, sizeof(int), cs->conts[i].nrverts*4, file);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateValues::debugWrite(FILE* file, const rcPolyMesh* mesh)
|
||||
{
|
||||
if (!file || !mesh)
|
||||
return;
|
||||
|
||||
fwrite(&(mesh->cs), sizeof(float), 1, file);
|
||||
fwrite(&(mesh->ch), sizeof(float), 1, file);
|
||||
fwrite(&(mesh->nvp), sizeof(int), 1, file);
|
||||
fwrite(mesh->bmin, sizeof(float), 3, file);
|
||||
fwrite(mesh->bmax, sizeof(float), 3, file);
|
||||
fwrite(&(mesh->nverts), sizeof(int), 1, file);
|
||||
fwrite(mesh->verts, sizeof(unsigned short), mesh->nverts*3, file);
|
||||
fwrite(&(mesh->npolys), sizeof(int), 1, file);
|
||||
fwrite(mesh->polys, sizeof(unsigned short), mesh->npolys*mesh->nvp*2, file);
|
||||
fwrite(mesh->flags, sizeof(unsigned short), mesh->npolys, file);
|
||||
fwrite(mesh->areas, sizeof(unsigned char), mesh->npolys, file);
|
||||
fwrite(mesh->regs, sizeof(unsigned short), mesh->npolys, file);
|
||||
}
|
||||
|
||||
void IntermediateValues::debugWrite(FILE* file, const rcPolyMeshDetail* mesh)
|
||||
{
|
||||
if (!file || !mesh)
|
||||
return;
|
||||
|
||||
fwrite(&(mesh->nverts), sizeof(int), 1, file);
|
||||
fwrite(mesh->verts, sizeof(float), mesh->nverts*3, file);
|
||||
fwrite(&(mesh->ntris), sizeof(int), 1, file);
|
||||
fwrite(mesh->tris, sizeof(char), mesh->ntris*4, file);
|
||||
fwrite(&(mesh->nmeshes), sizeof(int), 1, file);
|
||||
fwrite(mesh->meshes, sizeof(int), mesh->nmeshes*4, file);
|
||||
}
|
||||
|
||||
void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
|
||||
{
|
||||
char objFileName[255];
|
||||
sprintf(objFileName, "meshes/map%04u%02u%02u.obj", mapID, tileY, tileX);
|
||||
|
||||
FILE* objFile = fopen(objFileName, "wb");
|
||||
if (!objFile)
|
||||
{
|
||||
char message[1024];
|
||||
sprintf(message, "Failed to open %s for writing!\n", objFileName);
|
||||
perror(message);
|
||||
return;
|
||||
}
|
||||
|
||||
G3D::Array<float> allVerts;
|
||||
G3D::Array<int> allTris;
|
||||
|
||||
allTris.append(meshData.liquidTris);
|
||||
allVerts.append(meshData.liquidVerts);
|
||||
TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3);
|
||||
allVerts.append(meshData.solidVerts);
|
||||
|
||||
float* verts = allVerts.getCArray();
|
||||
int vertCount = allVerts.size() / 3;
|
||||
int* tris = allTris.getCArray();
|
||||
int triCount = allTris.size() / 3;
|
||||
|
||||
for (int i = 0; i < allVerts.size() / 3; i++)
|
||||
fprintf(objFile, "v %f %f %f\n", verts[i*3], verts[i*3 + 1], verts[i*3 + 2]);
|
||||
|
||||
for (int i = 0; i < allTris.size() / 3; i++)
|
||||
fprintf(objFile, "f %i %i %i\n", tris[i*3] + 1, tris[i*3 + 1] + 1, tris[i*3 + 2] + 1);
|
||||
|
||||
fclose(objFile);
|
||||
|
||||
|
||||
char tileString[25];
|
||||
sprintf(tileString, "[%02u,%02u]: ", tileY, tileX);
|
||||
printf("%sWriting debug output... \r", tileString);
|
||||
|
||||
sprintf(objFileName, "meshes/%04u.map", mapID);
|
||||
|
||||
objFile = fopen(objFileName, "wb");
|
||||
if (!objFile)
|
||||
{
|
||||
char message[1024];
|
||||
sprintf(message, "Failed to open %s for writing!\n", objFileName);
|
||||
perror(message);
|
||||
return;
|
||||
}
|
||||
|
||||
char b = '\0';
|
||||
fwrite(&b, sizeof(char), 1, objFile);
|
||||
fclose(objFile);
|
||||
|
||||
sprintf(objFileName, "meshes/%04u%02u%02u.mesh", mapID, tileY, tileX);
|
||||
objFile = fopen(objFileName, "wb");
|
||||
if (!objFile)
|
||||
{
|
||||
char message[1024];
|
||||
sprintf(message, "Failed to open %s for writing!\n", objFileName);
|
||||
perror(message);
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(&vertCount, sizeof(int), 1, objFile);
|
||||
fwrite(verts, sizeof(float), vertCount*3, objFile);
|
||||
fflush(objFile);
|
||||
|
||||
fwrite(&triCount, sizeof(int), 1, objFile);
|
||||
fwrite(tris, sizeof(int), triCount*3, objFile);
|
||||
fflush(objFile);
|
||||
|
||||
fclose(objFile);
|
||||
}
|
||||
}
|
||||
53
src/tools/mmaps_generator/IntermediateValues.h
Normal file
53
src/tools/mmaps_generator/IntermediateValues.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _INTERMEDIATE_VALUES_H
|
||||
#define _INTERMEDIATE_VALUES_H
|
||||
|
||||
#include "PathCommon.h"
|
||||
#include "TerrainBuilder.h"
|
||||
#include "Recast.h"
|
||||
#include "DetourNavMesh.h"
|
||||
|
||||
namespace MMAP
|
||||
{
|
||||
// this class gathers all debug info holding and output
|
||||
struct IntermediateValues
|
||||
{
|
||||
rcHeightfield* heightfield;
|
||||
rcCompactHeightfield* compactHeightfield;
|
||||
rcContourSet* contours;
|
||||
rcPolyMesh* polyMesh;
|
||||
rcPolyMeshDetail* polyMeshDetail;
|
||||
|
||||
IntermediateValues() : heightfield(NULL), compactHeightfield(NULL),
|
||||
contours(NULL), polyMesh(NULL), polyMeshDetail(NULL) {}
|
||||
~IntermediateValues();
|
||||
|
||||
void writeIV(uint32 mapID, uint32 tileX, uint32 tileY);
|
||||
|
||||
void debugWrite(FILE* file, const rcHeightfield* mesh);
|
||||
void debugWrite(FILE* file, const rcCompactHeightfield* chf);
|
||||
void debugWrite(FILE* file, const rcContourSet* cs);
|
||||
void debugWrite(FILE* file, const rcPolyMesh* mesh);
|
||||
void debugWrite(FILE* file, const rcPolyMeshDetail* mesh);
|
||||
|
||||
void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
1048
src/tools/mmaps_generator/MapBuilder.cpp
Normal file
1048
src/tools/mmaps_generator/MapBuilder.cpp
Normal file
File diff suppressed because it is too large
Load Diff
151
src/tools/mmaps_generator/MapBuilder.h
Normal file
151
src/tools/mmaps_generator/MapBuilder.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _MAP_BUILDER_H
|
||||
#define _MAP_BUILDER_H
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#include "TerrainBuilder.h"
|
||||
#include "IntermediateValues.h"
|
||||
|
||||
#include "Recast.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "ProducerConsumerQueue.h"
|
||||
|
||||
using namespace VMAP;
|
||||
|
||||
namespace MMAP
|
||||
{
|
||||
struct MapTiles
|
||||
{
|
||||
MapTiles() : m_mapId(uint32(-1)), m_tiles(NULL) {}
|
||||
|
||||
MapTiles(uint32 id, std::set<uint32>* tiles) : m_mapId(id), m_tiles(tiles) {}
|
||||
~MapTiles() {}
|
||||
|
||||
uint32 m_mapId;
|
||||
std::set<uint32>* m_tiles;
|
||||
|
||||
bool operator==(uint32 id)
|
||||
{
|
||||
return m_mapId == id;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::list<MapTiles> TileList;
|
||||
|
||||
struct Tile
|
||||
{
|
||||
Tile() : chf(NULL), solid(NULL), cset(NULL), pmesh(NULL), dmesh(NULL) {}
|
||||
~Tile()
|
||||
{
|
||||
rcFreeCompactHeightfield(chf);
|
||||
rcFreeContourSet(cset);
|
||||
rcFreeHeightField(solid);
|
||||
rcFreePolyMesh(pmesh);
|
||||
rcFreePolyMeshDetail(dmesh);
|
||||
}
|
||||
rcCompactHeightfield* chf;
|
||||
rcHeightfield* solid;
|
||||
rcContourSet* cset;
|
||||
rcPolyMesh* pmesh;
|
||||
rcPolyMeshDetail* dmesh;
|
||||
};
|
||||
|
||||
class MapBuilder
|
||||
{
|
||||
public:
|
||||
MapBuilder(float maxWalkableAngle = 70.f,
|
||||
bool skipLiquid = false,
|
||||
bool skipContinents = false,
|
||||
bool skipJunkMaps = true,
|
||||
bool skipBattlegrounds = false,
|
||||
bool debugOutput = false,
|
||||
bool bigBaseUnit = false,
|
||||
const char* offMeshFilePath = NULL);
|
||||
|
||||
~MapBuilder();
|
||||
|
||||
// builds all mmap tiles for the specified map id (ignores skip settings)
|
||||
void buildMap(uint32 mapID);
|
||||
void buildMeshFromFile(char* name);
|
||||
|
||||
// builds an mmap tile for the specified map and its mesh
|
||||
void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY);
|
||||
|
||||
// builds list of maps, then builds all of mmap tiles (based on the skip settings)
|
||||
void buildAllMaps(int threads);
|
||||
|
||||
void WorkerThread();
|
||||
|
||||
private:
|
||||
// detect maps and tiles
|
||||
void discoverTiles();
|
||||
std::set<uint32>* getTileList(uint32 mapID);
|
||||
|
||||
void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh);
|
||||
|
||||
void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh);
|
||||
|
||||
// move map building
|
||||
void buildMoveMapTile(uint32 mapID,
|
||||
uint32 tileX,
|
||||
uint32 tileY,
|
||||
MeshData &meshData,
|
||||
float bmin[3],
|
||||
float bmax[3],
|
||||
dtNavMesh* navMesh);
|
||||
|
||||
void getTileBounds(uint32 tileX, uint32 tileY,
|
||||
float* verts, int vertCount,
|
||||
float* bmin, float* bmax);
|
||||
void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY);
|
||||
|
||||
bool shouldSkipMap(uint32 mapID);
|
||||
bool isTransportMap(uint32 mapID);
|
||||
bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY);
|
||||
|
||||
TerrainBuilder* m_terrainBuilder;
|
||||
TileList m_tiles;
|
||||
|
||||
bool m_debugOutput;
|
||||
|
||||
const char* m_offMeshFilePath;
|
||||
bool m_skipContinents;
|
||||
bool m_skipJunkMaps;
|
||||
bool m_skipBattlegrounds;
|
||||
|
||||
float m_maxWalkableAngle;
|
||||
bool m_bigBaseUnit;
|
||||
|
||||
// build performance - not really used for now
|
||||
rcContext* m_rcContext;
|
||||
|
||||
std::vector<std::thread> _workerThreads;
|
||||
ProducerConsumerQueue<uint32> _queue;
|
||||
std::atomic<bool> _cancelationToken;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
139
src/tools/mmaps_generator/PathCommon.h
Normal file
139
src/tools/mmaps_generator/PathCommon.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _MMAP_COMMON_H
|
||||
#define _MMAP_COMMON_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <stddef.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
enum NavTerrain
|
||||
{
|
||||
NAV_EMPTY = 0x00,
|
||||
NAV_GROUND = 0x01,
|
||||
NAV_MAGMA = 0x02,
|
||||
NAV_SLIME = 0x04,
|
||||
NAV_WATER = 0x08,
|
||||
NAV_UNUSED1 = 0x10,
|
||||
NAV_UNUSED2 = 0x20,
|
||||
NAV_UNUSED3 = 0x40,
|
||||
NAV_UNUSED4 = 0x80
|
||||
// we only have 8 bits
|
||||
};
|
||||
|
||||
namespace MMAP
|
||||
{
|
||||
inline bool matchWildcardFilter(const char* filter, const char* str)
|
||||
{
|
||||
if (!filter || !str)
|
||||
return false;
|
||||
|
||||
// end on null character
|
||||
while (*filter && *str)
|
||||
{
|
||||
if (*filter == '*')
|
||||
{
|
||||
if (*++filter == '\0') // wildcard at end of filter means all remaing chars match
|
||||
return true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*filter == *str)
|
||||
break;
|
||||
if (*str == '\0')
|
||||
return false; // reached end of string without matching next filter character
|
||||
str++;
|
||||
}
|
||||
}
|
||||
else if (*filter != *str)
|
||||
return false; // mismatch
|
||||
|
||||
filter++;
|
||||
str++;
|
||||
}
|
||||
|
||||
return ((*filter == '\0' || (*filter == '*' && *++filter == '\0')) && *str == '\0');
|
||||
}
|
||||
|
||||
enum ListFilesResult
|
||||
{
|
||||
LISTFILE_DIRECTORY_NOT_FOUND = 0,
|
||||
LISTFILE_OK = 1
|
||||
};
|
||||
|
||||
inline ListFilesResult getDirContents(std::vector<std::string> &fileList, std::string dirpath = ".", std::string filter = "*")
|
||||
{
|
||||
#ifdef WIN32
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATA findFileInfo;
|
||||
std::string directory;
|
||||
|
||||
directory = dirpath + "/" + filter;
|
||||
|
||||
hFind = FindFirstFile(directory.c_str(), &findFileInfo);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return LISTFILE_DIRECTORY_NOT_FOUND;
|
||||
do
|
||||
{
|
||||
if ((findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||
fileList.push_back(std::string(findFileInfo.cFileName));
|
||||
}
|
||||
while (FindNextFile(hFind, &findFileInfo));
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
#else
|
||||
const char *p = dirpath.c_str();
|
||||
DIR * dirp = opendir(p);
|
||||
struct dirent * dp;
|
||||
|
||||
while (dirp)
|
||||
{
|
||||
errno = 0;
|
||||
if ((dp = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (matchWildcardFilter(filter.c_str(), dp->d_name))
|
||||
fileList.push_back(std::string(dp->d_name));
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (dirp)
|
||||
closedir(dirp);
|
||||
else
|
||||
return LISTFILE_DIRECTORY_NOT_FOUND;
|
||||
#endif
|
||||
|
||||
return LISTFILE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
310
src/tools/mmaps_generator/PathGenerator.cpp
Normal file
310
src/tools/mmaps_generator/PathGenerator.cpp
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "PathCommon.h"
|
||||
#include "MapBuilder.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include "Common.h"
|
||||
#include "Config.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "ProcessPriority.h"
|
||||
#include "Util.h"
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
using namespace MMAP;
|
||||
LoginDatabaseWorkerPool LoginDatabase;
|
||||
bool checkDirectories(bool debugOutput)
|
||||
{
|
||||
std::vector<std::string> dirFiles;
|
||||
|
||||
if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty())
|
||||
{
|
||||
printf("'maps' directory is empty or does not exist\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
dirFiles.clear();
|
||||
if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty())
|
||||
{
|
||||
printf("'vmaps' directory is empty or does not exist\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
dirFiles.clear();
|
||||
if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND)
|
||||
{
|
||||
printf("'mmaps' directory does not exist\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
dirFiles.clear();
|
||||
if (debugOutput)
|
||||
{
|
||||
if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND)
|
||||
{
|
||||
printf("'meshes' directory does not exist (no place to put debugOutput files)\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool handleArgs(int argc, char** argv,
|
||||
int &mapnum,
|
||||
int &tileX,
|
||||
int &tileY,
|
||||
float &maxAngle,
|
||||
bool &skipLiquid,
|
||||
bool &skipContinents,
|
||||
bool &skipJunkMaps,
|
||||
bool &skipBattlegrounds,
|
||||
bool &debugOutput,
|
||||
bool &silent,
|
||||
bool &bigBaseUnit,
|
||||
char* &offMeshInputPath,
|
||||
char* &file,
|
||||
int& threads)
|
||||
{
|
||||
char* param = NULL;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (strcmp(argv[i], "--maxAngle") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
|
||||
float maxangle = atof(param);
|
||||
if (maxangle <= 90.f && maxangle >= 45.f)
|
||||
maxAngle = maxangle;
|
||||
else
|
||||
printf("invalid option for '--maxAngle', using default\n");
|
||||
}
|
||||
else if (strcmp(argv[i], "--threads") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
threads = atoi(param);
|
||||
printf("Using %i threads to extract mmaps\n", threads);
|
||||
}
|
||||
else if (strcmp(argv[i], "--file") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
file = param;
|
||||
}
|
||||
else if (strcmp(argv[i], "--tile") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
|
||||
char* stileX = strtok(param, ",");
|
||||
char* stileY = strtok(NULL, ",");
|
||||
int tilex = atoi(stileX);
|
||||
int tiley = atoi(stileY);
|
||||
|
||||
if ((tilex > 0 && tilex < 64) || (tilex == 0 && strcmp(stileX, "0") == 0))
|
||||
tileX = tilex;
|
||||
if ((tiley > 0 && tiley < 64) || (tiley == 0 && strcmp(stileY, "0") == 0))
|
||||
tileY = tiley;
|
||||
|
||||
if (tileX < 0 || tileY < 0)
|
||||
{
|
||||
printf("invalid tile coords.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[i], "--skipLiquid") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
|
||||
if (strcmp(param, "true") == 0)
|
||||
skipLiquid = true;
|
||||
else if (strcmp(param, "false") == 0)
|
||||
skipLiquid = false;
|
||||
else
|
||||
printf("invalid option for '--skipLiquid', using default\n");
|
||||
}
|
||||
else if (strcmp(argv[i], "--skipContinents") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
|
||||
if (strcmp(param, "true") == 0)
|
||||
skipContinents = true;
|
||||
else if (strcmp(param, "false") == 0)
|
||||
skipContinents = false;
|
||||
else
|
||||
printf("invalid option for '--skipContinents', using default\n");
|
||||
}
|
||||
else if (strcmp(argv[i], "--skipJunkMaps") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
|
||||
if (strcmp(param, "true") == 0)
|
||||
skipJunkMaps = true;
|
||||
else if (strcmp(param, "false") == 0)
|
||||
skipJunkMaps = false;
|
||||
else
|
||||
printf("invalid option for '--skipJunkMaps', using default\n");
|
||||
}
|
||||
else if (strcmp(argv[i], "--skipBattlegrounds") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
|
||||
if (strcmp(param, "true") == 0)
|
||||
skipBattlegrounds = true;
|
||||
else if (strcmp(param, "false") == 0)
|
||||
skipBattlegrounds = false;
|
||||
else
|
||||
printf("invalid option for '--skipBattlegrounds', using default\n");
|
||||
}
|
||||
else if (strcmp(argv[i], "--debugOutput") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
|
||||
if (strcmp(param, "true") == 0)
|
||||
debugOutput = true;
|
||||
else if (strcmp(param, "false") == 0)
|
||||
debugOutput = false;
|
||||
else
|
||||
printf("invalid option for '--debugOutput', using default true\n");
|
||||
}
|
||||
else if (strcmp(argv[i], "--silent") == 0)
|
||||
{
|
||||
silent = true;
|
||||
}
|
||||
else if (strcmp(argv[i], "--bigBaseUnit") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
|
||||
if (strcmp(param, "true") == 0)
|
||||
bigBaseUnit = true;
|
||||
else if (strcmp(param, "false") == 0)
|
||||
bigBaseUnit = false;
|
||||
else
|
||||
printf("invalid option for '--bigBaseUnit', using default false\n");
|
||||
}
|
||||
else if (strcmp(argv[i], "--offMeshInput") == 0)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
|
||||
offMeshInputPath = param;
|
||||
}
|
||||
else
|
||||
{
|
||||
int map = atoi(argv[i]);
|
||||
if (map > 0 || (map == 0 && (strcmp(argv[i], "0") == 0)))
|
||||
mapnum = map;
|
||||
else
|
||||
{
|
||||
printf("invalid map id\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int finish(const char* message, int returnValue)
|
||||
{
|
||||
printf("%s", message);
|
||||
getchar(); // Wait for user input
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int threads = 3, mapnum = -1;
|
||||
float maxAngle = 70.0f;
|
||||
int tileX = -1, tileY = -1;
|
||||
bool skipLiquid = false,
|
||||
skipContinents = false,
|
||||
skipJunkMaps = true,
|
||||
skipBattlegrounds = false,
|
||||
debugOutput = false,
|
||||
silent = false,
|
||||
bigBaseUnit = false;
|
||||
char* offMeshInputPath = NULL;
|
||||
char* file = NULL;
|
||||
|
||||
bool validParam = handleArgs(argc, argv, mapnum,
|
||||
tileX, tileY, maxAngle,
|
||||
skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds,
|
||||
debugOutput, silent, bigBaseUnit, offMeshInputPath, file, threads);
|
||||
|
||||
if (!validParam)
|
||||
return silent ? -1 : finish("You have specified invalid parameters", -1);
|
||||
|
||||
if (mapnum == -1 && debugOutput)
|
||||
{
|
||||
if (silent)
|
||||
return -2;
|
||||
|
||||
printf("You have specifed debug output, but didn't specify a map to generate.\n");
|
||||
printf("This will generate debug output for ALL maps.\n");
|
||||
printf("Are you sure you want to continue? (y/n) ");
|
||||
if (getchar() != 'y')
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!checkDirectories(debugOutput))
|
||||
return silent ? -3 : finish("Press ENTER to close...", -3);
|
||||
|
||||
MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps,
|
||||
skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath);
|
||||
|
||||
uint32 start = getMSTime();
|
||||
if (file)
|
||||
builder.buildMeshFromFile(file);
|
||||
else if (tileX > -1 && tileY > -1 && mapnum >= 0)
|
||||
builder.buildSingleTile(mapnum, tileX, tileY);
|
||||
else if (mapnum >= 0)
|
||||
builder.buildMap(uint32(mapnum));
|
||||
else
|
||||
builder.buildAllMaps(threads);
|
||||
|
||||
if (!silent)
|
||||
printf("Finished. MMAPS were built in %u ms!\n", GetMSTimeDiffToNow(start));
|
||||
return 0;
|
||||
}
|
||||
928
src/tools/mmaps_generator/TerrainBuilder.cpp
Normal file
928
src/tools/mmaps_generator/TerrainBuilder.cpp
Normal file
@@ -0,0 +1,928 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "TerrainBuilder.h"
|
||||
|
||||
#include "MapBuilder.h"
|
||||
|
||||
#include "VMapManager2.h"
|
||||
#include "MapTree.h"
|
||||
#include "ModelInstance.h"
|
||||
|
||||
// ******************************************
|
||||
// Map file format defines
|
||||
// ******************************************
|
||||
struct map_fileheader
|
||||
{
|
||||
uint32 mapMagic;
|
||||
uint32 versionMagic;
|
||||
uint32 buildMagic;
|
||||
uint32 areaMapOffset;
|
||||
uint32 areaMapSize;
|
||||
uint32 heightMapOffset;
|
||||
uint32 heightMapSize;
|
||||
uint32 liquidMapOffset;
|
||||
uint32 liquidMapSize;
|
||||
uint32 holesOffset;
|
||||
uint32 holesSize;
|
||||
};
|
||||
|
||||
#define MAP_HEIGHT_NO_HEIGHT 0x0001
|
||||
#define MAP_HEIGHT_AS_INT16 0x0002
|
||||
#define MAP_HEIGHT_AS_INT8 0x0004
|
||||
|
||||
struct map_heightHeader
|
||||
{
|
||||
uint32 fourcc;
|
||||
uint32 flags;
|
||||
float gridHeight;
|
||||
float gridMaxHeight;
|
||||
};
|
||||
|
||||
#define MAP_LIQUID_NO_TYPE 0x0001
|
||||
#define MAP_LIQUID_NO_HEIGHT 0x0002
|
||||
|
||||
struct map_liquidHeader
|
||||
{
|
||||
uint32 fourcc;
|
||||
uint16 flags;
|
||||
uint16 liquidType;
|
||||
uint8 offsetX;
|
||||
uint8 offsetY;
|
||||
uint8 width;
|
||||
uint8 height;
|
||||
float liquidLevel;
|
||||
};
|
||||
|
||||
#define MAP_LIQUID_TYPE_NO_WATER 0x00
|
||||
#define MAP_LIQUID_TYPE_WATER 0x01
|
||||
#define MAP_LIQUID_TYPE_OCEAN 0x02
|
||||
#define MAP_LIQUID_TYPE_MAGMA 0x04
|
||||
#define MAP_LIQUID_TYPE_SLIME 0x08
|
||||
#define MAP_LIQUID_TYPE_DARK_WATER 0x10
|
||||
#define MAP_LIQUID_TYPE_WMO_WATER 0x20
|
||||
|
||||
namespace MMAP
|
||||
{
|
||||
|
||||
char const* MAP_VERSION_MAGIC = "v1.8";
|
||||
|
||||
TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ }
|
||||
TerrainBuilder::~TerrainBuilder() { }
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc)
|
||||
{
|
||||
switch (portion)
|
||||
{
|
||||
case ENTIRE:
|
||||
loopStart = 0;
|
||||
loopEnd = V8_SIZE_SQ;
|
||||
loopInc = 1;
|
||||
break;
|
||||
case TOP:
|
||||
loopStart = 0;
|
||||
loopEnd = V8_SIZE;
|
||||
loopInc = 1;
|
||||
break;
|
||||
case LEFT:
|
||||
loopStart = 0;
|
||||
loopEnd = V8_SIZE_SQ - V8_SIZE + 1;
|
||||
loopInc = V8_SIZE;
|
||||
break;
|
||||
case RIGHT:
|
||||
loopStart = V8_SIZE - 1;
|
||||
loopEnd = V8_SIZE_SQ;
|
||||
loopInc = V8_SIZE;
|
||||
break;
|
||||
case BOTTOM:
|
||||
loopStart = V8_SIZE_SQ - V8_SIZE;
|
||||
loopEnd = V8_SIZE_SQ;
|
||||
loopInc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
|
||||
{
|
||||
if (loadMap(mapID, tileX, tileY, meshData, ENTIRE))
|
||||
{
|
||||
loadMap(mapID, tileX+1, tileY, meshData, LEFT);
|
||||
loadMap(mapID, tileX-1, tileY, meshData, RIGHT);
|
||||
loadMap(mapID, tileX, tileY+1, meshData, TOP);
|
||||
loadMap(mapID, tileX, tileY-1, meshData, BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
bool TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion)
|
||||
{
|
||||
char mapFileName[255];
|
||||
sprintf(mapFileName, "maps/%04u_%02u_%02u.map", mapID, tileY, tileX);
|
||||
|
||||
FILE* mapFile = fopen(mapFileName, "rb");
|
||||
if (!mapFile)
|
||||
return false;
|
||||
|
||||
map_fileheader fheader;
|
||||
if (fread(&fheader, sizeof(map_fileheader), 1, mapFile) != 1 ||
|
||||
fheader.versionMagic != *((uint32 const*)(MAP_VERSION_MAGIC)))
|
||||
{
|
||||
fclose(mapFile);
|
||||
printf("%s is the wrong version, please extract new .map files\n", mapFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
map_heightHeader hheader;
|
||||
fseek(mapFile, fheader.heightMapOffset, SEEK_SET);
|
||||
|
||||
bool haveTerrain = false;
|
||||
bool haveLiquid = false;
|
||||
if (fread(&hheader, sizeof(map_heightHeader), 1, mapFile) == 1)
|
||||
{
|
||||
haveTerrain = !(hheader.flags & MAP_HEIGHT_NO_HEIGHT);
|
||||
haveLiquid = fheader.liquidMapOffset && !m_skipLiquid;
|
||||
}
|
||||
|
||||
// no data in this map file
|
||||
if (!haveTerrain && !haveLiquid)
|
||||
{
|
||||
fclose(mapFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
// data used later
|
||||
uint8 holes[16][16][8];
|
||||
memset(holes, 0, sizeof(holes));
|
||||
uint8 liquid_type[16][16];
|
||||
memset(liquid_type, 0, sizeof(liquid_type));
|
||||
G3D::Array<int> ltriangles;
|
||||
G3D::Array<int> ttriangles;
|
||||
|
||||
// terrain data
|
||||
if (haveTerrain)
|
||||
{
|
||||
float heightMultiplier;
|
||||
float V9[V9_SIZE_SQ], V8[V8_SIZE_SQ];
|
||||
int expected = V9_SIZE_SQ + V8_SIZE_SQ;
|
||||
|
||||
if (hheader.flags & MAP_HEIGHT_AS_INT8)
|
||||
{
|
||||
uint8 v9[V9_SIZE_SQ];
|
||||
uint8 v8[V8_SIZE_SQ];
|
||||
int count = 0;
|
||||
count += fread(v9, sizeof(uint8), V9_SIZE_SQ, mapFile);
|
||||
count += fread(v8, sizeof(uint8), V8_SIZE_SQ, mapFile);
|
||||
if (count != expected)
|
||||
printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
|
||||
|
||||
heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 255;
|
||||
|
||||
for (int i = 0; i < V9_SIZE_SQ; ++i)
|
||||
V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight;
|
||||
|
||||
for (int i = 0; i < V8_SIZE_SQ; ++i)
|
||||
V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight;
|
||||
}
|
||||
else if (hheader.flags & MAP_HEIGHT_AS_INT16)
|
||||
{
|
||||
uint16 v9[V9_SIZE_SQ];
|
||||
uint16 v8[V8_SIZE_SQ];
|
||||
int count = 0;
|
||||
count += fread(v9, sizeof(uint16), V9_SIZE_SQ, mapFile);
|
||||
count += fread(v8, sizeof(uint16), V8_SIZE_SQ, mapFile);
|
||||
if (count != expected)
|
||||
printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
|
||||
|
||||
heightMultiplier = (hheader.gridMaxHeight - hheader.gridHeight) / 65535;
|
||||
|
||||
for (int i = 0; i < V9_SIZE_SQ; ++i)
|
||||
V9[i] = (float)v9[i]*heightMultiplier + hheader.gridHeight;
|
||||
|
||||
for (int i = 0; i < V8_SIZE_SQ; ++i)
|
||||
V8[i] = (float)v8[i]*heightMultiplier + hheader.gridHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = 0;
|
||||
count += fread(V9, sizeof(float), V9_SIZE_SQ, mapFile);
|
||||
count += fread(V8, sizeof(float), V8_SIZE_SQ, mapFile);
|
||||
if (count != expected)
|
||||
printf("TerrainBuilder::loadMap: Failed to read some data expected %d, read %d\n", expected, count);
|
||||
}
|
||||
|
||||
// hole data
|
||||
if (fheader.holesSize != 0)
|
||||
{
|
||||
memset(holes, 0, fheader.holesSize);
|
||||
fseek(mapFile, fheader.holesOffset, SEEK_SET);
|
||||
if (fread(holes, fheader.holesSize, 1, mapFile) != 1)
|
||||
printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
|
||||
}
|
||||
|
||||
int count = meshData.solidVerts.size() / 3;
|
||||
float xoffset = (float(tileX)-32)*GRID_SIZE;
|
||||
float yoffset = (float(tileY)-32)*GRID_SIZE;
|
||||
|
||||
float coord[3];
|
||||
|
||||
for (int i = 0; i < V9_SIZE_SQ; ++i)
|
||||
{
|
||||
getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9);
|
||||
meshData.solidVerts.append(coord[0]);
|
||||
meshData.solidVerts.append(coord[2]);
|
||||
meshData.solidVerts.append(coord[1]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < V8_SIZE_SQ; ++i)
|
||||
{
|
||||
getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8);
|
||||
meshData.solidVerts.append(coord[0]);
|
||||
meshData.solidVerts.append(coord[2]);
|
||||
meshData.solidVerts.append(coord[1]);
|
||||
}
|
||||
|
||||
int indices[] = { 0, 0, 0 };
|
||||
int loopStart = 0, loopEnd = 0, loopInc = 0;
|
||||
getLoopVars(portion, loopStart, loopEnd, loopInc);
|
||||
for (int i = loopStart; i < loopEnd; i+=loopInc)
|
||||
for (int j = TOP; j <= BOTTOM; j+=1)
|
||||
{
|
||||
getHeightTriangle(i, Spot(j), indices);
|
||||
ttriangles.append(indices[2] + count);
|
||||
ttriangles.append(indices[1] + count);
|
||||
ttriangles.append(indices[0] + count);
|
||||
}
|
||||
}
|
||||
|
||||
// liquid data
|
||||
if (haveLiquid)
|
||||
{
|
||||
map_liquidHeader lheader;
|
||||
fseek(mapFile, fheader.liquidMapOffset, SEEK_SET);
|
||||
if (fread(&lheader, sizeof(map_liquidHeader), 1, mapFile) != 1)
|
||||
printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
|
||||
|
||||
|
||||
float* liquid_map = NULL;
|
||||
|
||||
if (!(lheader.flags & MAP_LIQUID_NO_TYPE))
|
||||
if (fread(liquid_type, sizeof(liquid_type), 1, mapFile) != 1)
|
||||
printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
|
||||
|
||||
if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT))
|
||||
{
|
||||
uint32 toRead = lheader.width * lheader.height;
|
||||
liquid_map = new float [toRead];
|
||||
if (fread(liquid_map, sizeof(float), toRead, mapFile) != toRead)
|
||||
printf("TerrainBuilder::loadMap: Failed to read some data expected 1, read 0\n");
|
||||
}
|
||||
|
||||
if (liquid_map)
|
||||
{
|
||||
int count = meshData.liquidVerts.size() / 3;
|
||||
float xoffset = (float(tileX)-32)*GRID_SIZE;
|
||||
float yoffset = (float(tileY)-32)*GRID_SIZE;
|
||||
|
||||
float coord[3];
|
||||
int row, col;
|
||||
|
||||
// generate coordinates
|
||||
if (!(lheader.flags & MAP_LIQUID_NO_HEIGHT))
|
||||
{
|
||||
int j = 0;
|
||||
for (int i = 0; i < V9_SIZE_SQ; ++i)
|
||||
{
|
||||
row = i / V9_SIZE;
|
||||
col = i % V9_SIZE;
|
||||
|
||||
if (row < lheader.offsetY || row >= lheader.offsetY + lheader.height ||
|
||||
col < lheader.offsetX || col >= lheader.offsetX + lheader.width)
|
||||
{
|
||||
// dummy vert using invalid height
|
||||
meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1);
|
||||
continue;
|
||||
}
|
||||
|
||||
getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map);
|
||||
meshData.liquidVerts.append(coord[0]);
|
||||
meshData.liquidVerts.append(coord[2]);
|
||||
meshData.liquidVerts.append(coord[1]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < V9_SIZE_SQ; ++i)
|
||||
{
|
||||
row = i / V9_SIZE;
|
||||
col = i % V9_SIZE;
|
||||
meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1);
|
||||
}
|
||||
}
|
||||
|
||||
delete [] liquid_map;
|
||||
|
||||
int indices[] = { 0, 0, 0 };
|
||||
int loopStart = 0, loopEnd = 0, loopInc = 0, triInc = BOTTOM-TOP;
|
||||
getLoopVars(portion, loopStart, loopEnd, loopInc);
|
||||
|
||||
// generate triangles
|
||||
for (int i = loopStart; i < loopEnd; i+=loopInc)
|
||||
for (int j = TOP; j <= BOTTOM; j+= triInc)
|
||||
{
|
||||
getHeightTriangle(i, Spot(j), indices, true);
|
||||
ltriangles.append(indices[2] + count);
|
||||
ltriangles.append(indices[1] + count);
|
||||
ltriangles.append(indices[0] + count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(mapFile);
|
||||
|
||||
// now that we have gathered the data, we can figure out which parts to keep:
|
||||
// liquid above ground, ground above liquid
|
||||
int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4;
|
||||
bool useTerrain, useLiquid;
|
||||
|
||||
float* lverts = meshData.liquidVerts.getCArray();
|
||||
int* ltris = ltriangles.getCArray();
|
||||
|
||||
float* tverts = meshData.solidVerts.getCArray();
|
||||
int* ttris = ttriangles.getCArray();
|
||||
|
||||
if ((ltriangles.size() + ttriangles.size()) == 0)
|
||||
return false;
|
||||
|
||||
// make a copy of liquid vertices
|
||||
// used to pad right-bottom frame due to lost vertex data at extraction
|
||||
float* lverts_copy = NULL;
|
||||
if (meshData.liquidVerts.size())
|
||||
{
|
||||
lverts_copy = new float[meshData.liquidVerts.size()];
|
||||
memcpy(lverts_copy, lverts, sizeof(float)*meshData.liquidVerts.size());
|
||||
}
|
||||
|
||||
getLoopVars(portion, loopStart, loopEnd, loopInc);
|
||||
for (int i = loopStart; i < loopEnd; i+=loopInc)
|
||||
{
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
// default is true, will change to false if needed
|
||||
useTerrain = true;
|
||||
useLiquid = true;
|
||||
uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER;
|
||||
// FIXME: "warning: the address of ‘liquid_type’ will always evaluate as ‘true’"
|
||||
|
||||
// if there is no liquid, don't use liquid
|
||||
if (!meshData.liquidVerts.size() || !ltriangles.size())
|
||||
useLiquid = false;
|
||||
else
|
||||
{
|
||||
liquidType = getLiquidType(i, liquid_type);
|
||||
switch (liquidType)
|
||||
{
|
||||
default:
|
||||
useLiquid = false;
|
||||
break;
|
||||
case MAP_LIQUID_TYPE_WATER:
|
||||
case MAP_LIQUID_TYPE_OCEAN:
|
||||
// merge different types of water
|
||||
liquidType = NAV_WATER;
|
||||
break;
|
||||
case MAP_LIQUID_TYPE_MAGMA:
|
||||
liquidType = NAV_MAGMA;
|
||||
break;
|
||||
case MAP_LIQUID_TYPE_SLIME:
|
||||
liquidType = NAV_SLIME;
|
||||
break;
|
||||
case MAP_LIQUID_TYPE_DARK_WATER:
|
||||
// players should not be here, so logically neither should creatures
|
||||
useTerrain = false;
|
||||
useLiquid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if there is no terrain, don't use terrain
|
||||
if (!ttriangles.size())
|
||||
useTerrain = false;
|
||||
|
||||
// while extracting ADT data we are losing right-bottom vertices
|
||||
// this code adds fair approximation of lost data
|
||||
if (useLiquid)
|
||||
{
|
||||
float quadHeight = 0;
|
||||
uint32 validCount = 0;
|
||||
for(uint32 idx = 0; idx < 3; idx++)
|
||||
{
|
||||
float h = lverts_copy[ltris[idx]*3 + 1];
|
||||
if (h != INVALID_MAP_LIQ_HEIGHT && h < INVALID_MAP_LIQ_HEIGHT_MAX)
|
||||
{
|
||||
quadHeight += h;
|
||||
validCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// update vertex height data
|
||||
if (validCount > 0 && validCount < 3)
|
||||
{
|
||||
quadHeight /= validCount;
|
||||
for(uint32 idx = 0; idx < 3; idx++)
|
||||
{
|
||||
float h = lverts[ltris[idx]*3 + 1];
|
||||
if (h == INVALID_MAP_LIQ_HEIGHT || h > INVALID_MAP_LIQ_HEIGHT_MAX)
|
||||
lverts[ltris[idx]*3 + 1] = quadHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// no valid vertexes - don't use this poly at all
|
||||
if (validCount == 0)
|
||||
useLiquid = false;
|
||||
}
|
||||
|
||||
// if there is a hole here, don't use the terrain
|
||||
if (useTerrain && fheader.holesSize != 0)
|
||||
useTerrain = !isHole(i, holes);
|
||||
|
||||
// we use only one terrain kind per quad - pick higher one
|
||||
if (useTerrain && useLiquid)
|
||||
{
|
||||
float minLLevel = INVALID_MAP_LIQ_HEIGHT_MAX;
|
||||
float maxLLevel = INVALID_MAP_LIQ_HEIGHT;
|
||||
for(uint32 x = 0; x < 3; x++)
|
||||
{
|
||||
float h = lverts[ltris[x]*3 + 1];
|
||||
if (minLLevel > h)
|
||||
minLLevel = h;
|
||||
|
||||
if (maxLLevel < h)
|
||||
maxLLevel = h;
|
||||
}
|
||||
|
||||
float maxTLevel = INVALID_MAP_LIQ_HEIGHT;
|
||||
float minTLevel = INVALID_MAP_LIQ_HEIGHT_MAX;
|
||||
for(uint32 x = 0; x < 6; x++)
|
||||
{
|
||||
float h = tverts[ttris[x]*3 + 1];
|
||||
if (maxTLevel < h)
|
||||
maxTLevel = h;
|
||||
|
||||
if (minTLevel > h)
|
||||
minTLevel = h;
|
||||
}
|
||||
|
||||
// terrain under the liquid?
|
||||
if (minLLevel > maxTLevel)
|
||||
useTerrain = false;
|
||||
|
||||
//liquid under the terrain?
|
||||
if (minTLevel > maxLLevel)
|
||||
useLiquid = false;
|
||||
}
|
||||
|
||||
// store the result
|
||||
if (useLiquid)
|
||||
{
|
||||
meshData.liquidType.append(liquidType);
|
||||
for (int k = 0; k < 3; ++k)
|
||||
meshData.liquidTris.append(ltris[k]);
|
||||
}
|
||||
|
||||
if (useTerrain)
|
||||
for (int k = 0; k < 3*tTriCount/2; ++k)
|
||||
meshData.solidTris.append(ttris[k]);
|
||||
|
||||
// advance to next set of triangles
|
||||
ltris += 3;
|
||||
ttris += 3*tTriCount/2;
|
||||
}
|
||||
}
|
||||
|
||||
if (lverts_copy)
|
||||
delete [] lverts_copy;
|
||||
|
||||
return meshData.solidTris.size() || meshData.liquidTris.size();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v)
|
||||
{
|
||||
// wow coords: x, y, height
|
||||
// coord is mirroed about the horizontal axes
|
||||
switch (grid)
|
||||
{
|
||||
case GRID_V9:
|
||||
coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f;
|
||||
coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f;
|
||||
coord[2] = v[index];
|
||||
break;
|
||||
case GRID_V8:
|
||||
coord[0] = (xOffset + index%(V8_SIZE)*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f;
|
||||
coord[1] = (yOffset + (int)(index/(V8_SIZE))*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f;
|
||||
coord[2] = v[index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, bool liquid/* = false*/)
|
||||
{
|
||||
int rowOffset = square/V8_SIZE;
|
||||
if (!liquid)
|
||||
switch (triangle)
|
||||
{
|
||||
case TOP:
|
||||
indices[0] = square+rowOffset; // 0-----1 .... 128
|
||||
indices[1] = square+1+rowOffset; // |\ T /|
|
||||
indices[2] = (V9_SIZE_SQ)+square; // | \ / |
|
||||
break; // |L 0 R| .. 127
|
||||
case LEFT: // | / \ |
|
||||
indices[0] = square+rowOffset; // |/ B \|
|
||||
indices[1] = (V9_SIZE_SQ)+square; // 129---130 ... 386
|
||||
indices[2] = square+V9_SIZE+rowOffset; // |\ /|
|
||||
break; // | \ / |
|
||||
case RIGHT: // | 128 | .. 255
|
||||
indices[0] = square+1+rowOffset; // | / \ |
|
||||
indices[1] = square+V9_SIZE+1+rowOffset; // |/ \|
|
||||
indices[2] = (V9_SIZE_SQ)+square; // 258---259 ... 515
|
||||
break;
|
||||
case BOTTOM:
|
||||
indices[0] = (V9_SIZE_SQ)+square;
|
||||
indices[1] = square+V9_SIZE+1+rowOffset;
|
||||
indices[2] = square+V9_SIZE+rowOffset;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
else
|
||||
switch (triangle)
|
||||
{ // 0-----1 .... 128
|
||||
case TOP: // |\ |
|
||||
indices[0] = square+rowOffset; // | \ T |
|
||||
indices[1] = square+1+rowOffset; // | \ |
|
||||
indices[2] = square+V9_SIZE+1+rowOffset; // | B \ |
|
||||
break; // | \|
|
||||
case BOTTOM: // 129---130 ... 386
|
||||
indices[0] = square+rowOffset; // |\ |
|
||||
indices[1] = square+V9_SIZE+1+rowOffset; // | \ |
|
||||
indices[2] = square+V9_SIZE+rowOffset; // | \ |
|
||||
break; // | \ |
|
||||
default: break; // | \|
|
||||
} // 258---259 ... 515
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v)
|
||||
{
|
||||
// wow coords: x, y, height
|
||||
// coord is mirroed about the horizontal axes
|
||||
coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f;
|
||||
coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f;
|
||||
coord[2] = v[index2];
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
bool TerrainBuilder::isHole(int square, uint8 const holes[16][16][8])
|
||||
{
|
||||
int row = square / 128;
|
||||
int col = square % 128;
|
||||
int cellRow = row / 8; // 8 squares per cell
|
||||
int cellCol = col / 8;
|
||||
int holeRow = row % 8;
|
||||
int holeCol = (square - (row * 128 + cellCol * 8));
|
||||
|
||||
return (holes[cellRow][cellCol][holeRow] & (1 << holeCol)) != 0;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
uint8 TerrainBuilder::getLiquidType(int square, const uint8 liquid_type[16][16])
|
||||
{
|
||||
int row = square / 128;
|
||||
int col = square % 128;
|
||||
int cellRow = row / 8; // 8 squares per cell
|
||||
int cellCol = col / 8;
|
||||
|
||||
return liquid_type[cellRow][cellCol];
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
|
||||
{
|
||||
IVMapManager* vmapManager = new VMapManager2();
|
||||
int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY);
|
||||
bool retval = false;
|
||||
|
||||
do
|
||||
{
|
||||
if (result == VMAP_LOAD_RESULT_ERROR)
|
||||
break;
|
||||
|
||||
InstanceTreeMap instanceTrees;
|
||||
((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees);
|
||||
|
||||
if (!instanceTrees[mapID])
|
||||
break;
|
||||
|
||||
ModelInstance* models = NULL;
|
||||
uint32 count = 0;
|
||||
instanceTrees[mapID]->getModelInstances(models, count);
|
||||
|
||||
if (!models)
|
||||
break;
|
||||
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
ModelInstance instance = models[i];
|
||||
|
||||
// model instances exist in tree even though there are instances of that model in this tile
|
||||
WorldModel* worldModel = instance.getWorldModel();
|
||||
if (!worldModel)
|
||||
continue;
|
||||
|
||||
// now we have a model to add to the meshdata
|
||||
retval = true;
|
||||
|
||||
std::vector<GroupModel> groupModels;
|
||||
worldModel->getGroupModels(groupModels);
|
||||
|
||||
// all M2s need to have triangle indices reversed
|
||||
bool isM2 = instance.name.find(".m2") != std::string::npos || instance.name.find(".M2") != std::string::npos;
|
||||
|
||||
// transform data
|
||||
float scale = instance.iScale;
|
||||
G3D::Matrix3 rotation = G3D::Matrix3::fromEulerAnglesXYZ(G3D::pi()*instance.iRot.z/-180.f, G3D::pi()*instance.iRot.x/-180.f, G3D::pi()*instance.iRot.y/-180.f);
|
||||
G3D::Vector3 position = instance.iPos;
|
||||
position.x -= 32*GRID_SIZE;
|
||||
position.y -= 32*GRID_SIZE;
|
||||
|
||||
for (std::vector<GroupModel>::iterator it = groupModels.begin(); it != groupModels.end(); ++it)
|
||||
{
|
||||
std::vector<G3D::Vector3> tempVertices;
|
||||
std::vector<G3D::Vector3> transformedVertices;
|
||||
std::vector<MeshTriangle> tempTriangles;
|
||||
WmoLiquid* liquid = NULL;
|
||||
|
||||
it->getMeshData(tempVertices, tempTriangles, liquid);
|
||||
|
||||
// first handle collision mesh
|
||||
transform(tempVertices, transformedVertices, scale, rotation, position);
|
||||
|
||||
int offset = meshData.solidVerts.size() / 3;
|
||||
|
||||
copyVertices(transformedVertices, meshData.solidVerts);
|
||||
copyIndices(tempTriangles, meshData.solidTris, offset, isM2);
|
||||
|
||||
// now handle liquid data
|
||||
if (liquid)
|
||||
{
|
||||
std::vector<G3D::Vector3> liqVerts;
|
||||
std::vector<int> liqTris;
|
||||
uint32 tilesX, tilesY, vertsX, vertsY;
|
||||
G3D::Vector3 corner;
|
||||
liquid->getPosInfo(tilesX, tilesY, corner);
|
||||
vertsX = tilesX + 1;
|
||||
vertsY = tilesY + 1;
|
||||
uint8* flags = liquid->GetFlagsStorage();
|
||||
float* data = liquid->GetHeightStorage();
|
||||
uint8 type = NAV_EMPTY;
|
||||
|
||||
// convert liquid type to NavTerrain
|
||||
switch (liquid->GetType())
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
type = NAV_WATER;
|
||||
break;
|
||||
case 2:
|
||||
type = NAV_MAGMA;
|
||||
break;
|
||||
case 3:
|
||||
type = NAV_SLIME;
|
||||
break;
|
||||
}
|
||||
|
||||
// indexing is weird...
|
||||
// after a lot of trial and error, this is what works:
|
||||
// vertex = y*vertsX+x
|
||||
// tile = x*tilesY+y
|
||||
// flag = y*tilesY+x
|
||||
|
||||
G3D::Vector3 vert;
|
||||
for (uint32 x = 0; x < vertsX; ++x)
|
||||
for (uint32 y = 0; y < vertsY; ++y)
|
||||
{
|
||||
vert = G3D::Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y*vertsX + x]);
|
||||
vert = vert * rotation * scale + position;
|
||||
vert.x *= -1.f;
|
||||
vert.y *= -1.f;
|
||||
liqVerts.push_back(vert);
|
||||
}
|
||||
|
||||
int idx1, idx2, idx3, idx4;
|
||||
uint32 square;
|
||||
for (uint32 x = 0; x < tilesX; ++x)
|
||||
for (uint32 y = 0; y < tilesY; ++y)
|
||||
if ((flags[x+y*tilesX] & 0x0f) != 0x0f)
|
||||
{
|
||||
square = x * tilesY + y;
|
||||
idx1 = square+x;
|
||||
idx2 = square+1+x;
|
||||
idx3 = square+tilesY+1+1+x;
|
||||
idx4 = square+tilesY+1+x;
|
||||
|
||||
// top triangle
|
||||
liqTris.push_back(idx3);
|
||||
liqTris.push_back(idx2);
|
||||
liqTris.push_back(idx1);
|
||||
// bottom triangle
|
||||
liqTris.push_back(idx4);
|
||||
liqTris.push_back(idx3);
|
||||
liqTris.push_back(idx1);
|
||||
}
|
||||
|
||||
uint32 liqOffset = meshData.liquidVerts.size() / 3;
|
||||
for (uint32 i = 0; i < liqVerts.size(); ++i)
|
||||
meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x);
|
||||
|
||||
for (uint32 i = 0; i < liqTris.size() / 3; ++i)
|
||||
{
|
||||
meshData.liquidTris.append(liqTris[i*3+1] + liqOffset, liqTris[i*3+2] + liqOffset, liqTris[i*3] + liqOffset);
|
||||
meshData.liquidType.append(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (false);
|
||||
|
||||
vmapManager->unloadMap(mapID, tileX, tileY);
|
||||
delete vmapManager;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::transform(std::vector<G3D::Vector3> &source, std::vector<G3D::Vector3> &transformedVertices, float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position)
|
||||
{
|
||||
for (std::vector<G3D::Vector3>::iterator it = source.begin(); it != source.end(); ++it)
|
||||
{
|
||||
// apply tranform, then mirror along the horizontal axes
|
||||
G3D::Vector3 v((*it) * rotation * scale + position);
|
||||
v.x *= -1.f;
|
||||
v.y *= -1.f;
|
||||
transformedVertices.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::copyVertices(std::vector<G3D::Vector3> &source, G3D::Array<float> &dest)
|
||||
{
|
||||
for (std::vector<G3D::Vector3>::iterator it = source.begin(); it != source.end(); ++it)
|
||||
{
|
||||
dest.push_back((*it).y);
|
||||
dest.push_back((*it).z);
|
||||
dest.push_back((*it).x);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::copyIndices(std::vector<MeshTriangle> &source, G3D::Array<int> &dest, int offset, bool flip)
|
||||
{
|
||||
if (flip)
|
||||
{
|
||||
for (std::vector<MeshTriangle>::iterator it = source.begin(); it != source.end(); ++it)
|
||||
{
|
||||
dest.push_back((*it).idx2+offset);
|
||||
dest.push_back((*it).idx1+offset);
|
||||
dest.push_back((*it).idx0+offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::vector<MeshTriangle>::iterator it = source.begin(); it != source.end(); ++it)
|
||||
{
|
||||
dest.push_back((*it).idx0+offset);
|
||||
dest.push_back((*it).idx1+offset);
|
||||
dest.push_back((*it).idx2+offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::copyIndices(G3D::Array<int> &source, G3D::Array<int> &dest, int offset)
|
||||
{
|
||||
int* src = source.getCArray();
|
||||
for (int32 i = 0; i < source.size(); ++i)
|
||||
dest.append(src[i] + offset);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::cleanVertices(G3D::Array<float> &verts, G3D::Array<int> &tris)
|
||||
{
|
||||
std::map<int, int> vertMap;
|
||||
|
||||
int* t = tris.getCArray();
|
||||
float* v = verts.getCArray();
|
||||
|
||||
G3D::Array<float> cleanVerts;
|
||||
int index, count = 0;
|
||||
// collect all the vertex indices from triangle
|
||||
for (int i = 0; i < tris.size(); ++i)
|
||||
{
|
||||
if (vertMap.find(t[i]) != vertMap.end())
|
||||
continue;
|
||||
std::pair<int, int> val;
|
||||
val.first = t[i];
|
||||
|
||||
index = val.first;
|
||||
val.second = count;
|
||||
|
||||
vertMap.insert(val);
|
||||
cleanVerts.append(v[index * 3], v[index * 3 + 1], v[index * 3 + 2]);
|
||||
count++;
|
||||
}
|
||||
|
||||
verts.fastClear();
|
||||
verts.append(cleanVerts);
|
||||
cleanVerts.clear();
|
||||
|
||||
// update triangles to use new indices
|
||||
for (int i = 0; i < tris.size(); ++i)
|
||||
{
|
||||
std::map<int, int>::iterator it;
|
||||
if ((it = vertMap.find(t[i])) == vertMap.end())
|
||||
continue;
|
||||
|
||||
t[i] = (*it).second;
|
||||
}
|
||||
|
||||
vertMap.clear();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath)
|
||||
{
|
||||
// no meshfile input given?
|
||||
if (offMeshFilePath == NULL)
|
||||
return;
|
||||
|
||||
FILE* fp = fopen(offMeshFilePath, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
printf(" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath);
|
||||
return;
|
||||
}
|
||||
|
||||
// pretty silly thing, as we parse entire file and load only the tile we need
|
||||
// but we don't expect this file to be too large
|
||||
char* buf = new char[512];
|
||||
while(fgets(buf, 512, fp))
|
||||
{
|
||||
float p0[3], p1[3];
|
||||
uint32 mid, tx, ty;
|
||||
float size;
|
||||
if (sscanf(buf, "%u %u,%u (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty,
|
||||
&p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size) != 10)
|
||||
continue;
|
||||
|
||||
if (mapID == mid && tileX == tx && tileY == ty)
|
||||
{
|
||||
meshData.offMeshConnections.append(p0[1]);
|
||||
meshData.offMeshConnections.append(p0[2]);
|
||||
meshData.offMeshConnections.append(p0[0]);
|
||||
|
||||
meshData.offMeshConnections.append(p1[1]);
|
||||
meshData.offMeshConnections.append(p1[2]);
|
||||
meshData.offMeshConnections.append(p1[0]);
|
||||
|
||||
meshData.offMeshConnectionDirs.append(1); // 1 - both direction, 0 - one sided
|
||||
meshData.offMeshConnectionRads.append(size); // agent size equivalent
|
||||
// can be used same way as polygon flags
|
||||
meshData.offMeshConnectionsAreas.append((unsigned char)0xFF);
|
||||
meshData.offMeshConnectionsFlags.append((unsigned short)0xFF); // all movement masks can make this path
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete [] buf;
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
132
src/tools/mmaps_generator/TerrainBuilder.h
Normal file
132
src/tools/mmaps_generator/TerrainBuilder.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _MMAP_TERRAIN_BUILDER_H
|
||||
#define _MMAP_TERRAIN_BUILDER_H
|
||||
|
||||
#include "PathCommon.h"
|
||||
#include "WorldModel.h"
|
||||
|
||||
#include "G3D/Array.h"
|
||||
#include "G3D/Vector3.h"
|
||||
#include "G3D/Matrix3.h"
|
||||
|
||||
namespace MMAP
|
||||
{
|
||||
enum Spot
|
||||
{
|
||||
TOP = 1,
|
||||
RIGHT = 2,
|
||||
LEFT = 3,
|
||||
BOTTOM = 4,
|
||||
ENTIRE = 5
|
||||
};
|
||||
|
||||
enum Grid
|
||||
{
|
||||
GRID_V8,
|
||||
GRID_V9
|
||||
};
|
||||
|
||||
static const int V9_SIZE = 129;
|
||||
static const int V9_SIZE_SQ = V9_SIZE*V9_SIZE;
|
||||
static const int V8_SIZE = 128;
|
||||
static const int V8_SIZE_SQ = V8_SIZE*V8_SIZE;
|
||||
static const float GRID_SIZE = 533.3333f;
|
||||
static const float GRID_PART_SIZE = GRID_SIZE/V8_SIZE;
|
||||
|
||||
// see contrib/extractor/system.cpp, CONF_use_minHeight
|
||||
static const float INVALID_MAP_LIQ_HEIGHT = -500.f;
|
||||
static const float INVALID_MAP_LIQ_HEIGHT_MAX = 5000.0f;
|
||||
|
||||
// see following files:
|
||||
// contrib/extractor/system.cpp
|
||||
// src/game/Map.cpp
|
||||
|
||||
struct MeshData
|
||||
{
|
||||
G3D::Array<float> solidVerts;
|
||||
G3D::Array<int> solidTris;
|
||||
|
||||
G3D::Array<float> liquidVerts;
|
||||
G3D::Array<int> liquidTris;
|
||||
G3D::Array<uint8> liquidType;
|
||||
|
||||
// offmesh connection data
|
||||
G3D::Array<float> offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection
|
||||
G3D::Array<float> offMeshConnectionRads;
|
||||
G3D::Array<unsigned char> offMeshConnectionDirs;
|
||||
G3D::Array<unsigned char> offMeshConnectionsAreas;
|
||||
G3D::Array<unsigned short> offMeshConnectionsFlags;
|
||||
};
|
||||
|
||||
class TerrainBuilder
|
||||
{
|
||||
public:
|
||||
TerrainBuilder(bool skipLiquid);
|
||||
~TerrainBuilder();
|
||||
|
||||
void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData);
|
||||
bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData);
|
||||
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char* offMeshFilePath);
|
||||
|
||||
bool usesLiquids() { return !m_skipLiquid; }
|
||||
|
||||
// vert and triangle methods
|
||||
static void transform(std::vector<G3D::Vector3> &original, std::vector<G3D::Vector3> &transformed,
|
||||
float scale, G3D::Matrix3 &rotation, G3D::Vector3 &position);
|
||||
static void copyVertices(std::vector<G3D::Vector3> &source, G3D::Array<float> &dest);
|
||||
static void copyIndices(std::vector<VMAP::MeshTriangle> &source, G3D::Array<int> &dest, int offest, bool flip);
|
||||
static void copyIndices(G3D::Array<int> &src, G3D::Array<int> &dest, int offset);
|
||||
static void cleanVertices(G3D::Array<float> &verts, G3D::Array<int> &tris);
|
||||
private:
|
||||
/// Loads a portion of a map's terrain
|
||||
bool loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion);
|
||||
|
||||
/// Sets loop variables for selecting only certain parts of a map's terrain
|
||||
void getLoopVars(Spot portion, int &loopStart, int &loopEnd, int &loopInc);
|
||||
|
||||
/// Controls whether liquids are loaded
|
||||
bool m_skipLiquid;
|
||||
|
||||
/// Load the map terrain from file
|
||||
bool loadHeightMap(uint32 mapID, uint32 tileX, uint32 tileY, G3D::Array<float> &vertices, G3D::Array<int> &triangles, Spot portion);
|
||||
|
||||
/// Get the vector coordinate for a specific position
|
||||
void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v);
|
||||
|
||||
/// Get the triangle's vector indices for a specific position
|
||||
void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false);
|
||||
|
||||
/// Determines if the specific position's triangles should be rendered
|
||||
bool isHole(int square, uint8 const holes[16][16][8]);
|
||||
|
||||
/// Get the liquid vector coordinate for a specific position
|
||||
void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v);
|
||||
|
||||
/// Get the liquid type for a specific position
|
||||
uint8 getLiquidType(int square, const uint8 liquid_type[16][16]);
|
||||
|
||||
// hide parameterless and copy constructor
|
||||
TerrainBuilder();
|
||||
TerrainBuilder(const TerrainBuilder &tb);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
23
src/tools/mmaps_generator/VMapExtensions.cpp
Normal file
23
src/tools/mmaps_generator/VMapExtensions.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include "MapTree.h"
|
||||
#include "VMapManager2.h"
|
||||
#include "WorldModel.h"
|
||||
#include "ModelInstance.h"
|
||||
36
src/tools/vmap4_assembler/CMakeLists.txt
Normal file
36
src/tools/vmap4_assembler/CMakeLists.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
|
||||
# Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision/Maps
|
||||
${CMAKE_SOURCE_DIR}/src/server/collision/Models
|
||||
${ACE_INCLUDE_DIR}
|
||||
${ZLIB_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
add_executable(vmap4assembler VMapAssembler.cpp)
|
||||
add_dependencies(vmap4assembler casc)
|
||||
|
||||
target_link_libraries(vmap4assembler
|
||||
g3dlib
|
||||
common
|
||||
${ZLIB_LIBRARIES}
|
||||
)
|
||||
|
||||
if( UNIX )
|
||||
install(TARGETS vmap4assembler DESTINATION bin)
|
||||
elseif( WIN32 )
|
||||
install(TARGETS vmap4assembler DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
49
src/tools/vmap4_assembler/VMapAssembler.cpp
Normal file
49
src/tools/vmap4_assembler/VMapAssembler.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "TileAssembler.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
std::cout << "usage: " << argv[0] << " <raw data dir> <vmap dest dir>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string src = argv[1];
|
||||
std::string dest = argv[2];
|
||||
|
||||
std::cout << "using " << src << " as source directory and writing output to " << dest << std::endl;
|
||||
|
||||
VMAP::TileAssembler* ta = new VMAP::TileAssembler(src, dest);
|
||||
|
||||
if (!ta->convertWorld2())
|
||||
{
|
||||
std::cout << "exit with errors" << std::endl;
|
||||
delete ta;
|
||||
return 1;
|
||||
}
|
||||
|
||||
delete ta;
|
||||
std::cout << "Ok, all done" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
46
src/tools/vmap4_extractor/CMakeLists.txt
Normal file
46
src/tools/vmap4_extractor/CMakeLists.txt
Normal file
@@ -0,0 +1,46 @@
|
||||
# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
|
||||
# Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
file(GLOB_RECURSE sources *.cpp *.h)
|
||||
|
||||
# uncomment next line to disable debug mode
|
||||
add_definitions("-DIOMAP_DEBUG")
|
||||
|
||||
# build setup currently only supports libmpq 0.4.x
|
||||
if( NOT MSVC )
|
||||
add_definitions("-Wall")
|
||||
add_definitions("-ggdb")
|
||||
add_definitions("-O3")
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/src/server/shared
|
||||
${CMAKE_SOURCE_DIR}/dep/CascLib/src
|
||||
${CMAKE_SOURCE_DIR}/dep/cppformat
|
||||
)
|
||||
|
||||
add_executable(vmap4extractor ${sources})
|
||||
|
||||
target_link_libraries(vmap4extractor
|
||||
casc
|
||||
common
|
||||
${BZIP2_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
)
|
||||
|
||||
add_dependencies(vmap4extractor casc)
|
||||
|
||||
if( UNIX )
|
||||
install(TARGETS vmap4extractor DESTINATION bin)
|
||||
elseif( WIN32 )
|
||||
install(TARGETS vmap4extractor DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
204
src/tools/vmap4_extractor/adtfile.cpp
Normal file
204
src/tools/vmap4_extractor/adtfile.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "adtfile.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
char const* GetPlainName(char const* FileName)
|
||||
{
|
||||
const char * szTemp;
|
||||
|
||||
if ((szTemp = strrchr(FileName, '\\')) != NULL)
|
||||
FileName = szTemp + 1;
|
||||
return FileName;
|
||||
}
|
||||
|
||||
char* GetPlainName(char* FileName)
|
||||
{
|
||||
char * szTemp;
|
||||
|
||||
if ((szTemp = strrchr(FileName, '\\')) != NULL)
|
||||
FileName = szTemp + 1;
|
||||
return FileName;
|
||||
}
|
||||
|
||||
void FixNameCase(char* name, size_t len)
|
||||
{
|
||||
char* ptr = name + len - 1;
|
||||
|
||||
//extension in lowercase
|
||||
for (; *ptr != '.'; --ptr)
|
||||
*ptr |= 0x20;
|
||||
|
||||
for (; ptr >= name; --ptr)
|
||||
{
|
||||
if (ptr > name && *ptr >= 'A' && *ptr <= 'Z' && isalpha(*(ptr - 1)))
|
||||
*ptr |= 0x20;
|
||||
else if ((ptr == name || !isalpha(*(ptr - 1))) && *ptr >= 'a' && *ptr <= 'z')
|
||||
*ptr &= ~0x20;
|
||||
}
|
||||
}
|
||||
|
||||
void FixNameSpaces(char* name, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len - 3; i++)
|
||||
{
|
||||
if (name[i] == ' ')
|
||||
name[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
char* GetExtension(char* FileName)
|
||||
{
|
||||
if (char* szTemp = strrchr(FileName, '.'))
|
||||
return szTemp;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ADTFile::ADTFile(char* filename) : ADT(filename), nWMO(0), nMDX(0)
|
||||
{
|
||||
Adtfilename.append(filename);
|
||||
}
|
||||
|
||||
bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
|
||||
{
|
||||
if (ADT.isEof())
|
||||
return false;
|
||||
|
||||
uint32 size;
|
||||
std::string dirname = std::string(szWorkDirWmo) + "/dir_bin";
|
||||
FILE *dirfile;
|
||||
dirfile = fopen(dirname.c_str(), "ab");
|
||||
if (!dirfile)
|
||||
{
|
||||
// printf("Can't open dirfile!'%s'\n", dirname.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!ADT.isEof())
|
||||
{
|
||||
char fourcc[5];
|
||||
ADT.read(&fourcc,4);
|
||||
ADT.read(&size, 4);
|
||||
flipcc(fourcc);
|
||||
fourcc[4] = 0;
|
||||
|
||||
size_t nextpos = ADT.getPos() + size;
|
||||
|
||||
if (!strcmp(fourcc,"MCIN"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MTEX"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MMDX"))
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
char* buf = new char[size];
|
||||
ADT.read(buf, size);
|
||||
char* p = buf;
|
||||
while (p < buf + size)
|
||||
{
|
||||
std::string path(p);
|
||||
|
||||
char* s = GetPlainName(p);
|
||||
FixNameCase(s, strlen(s));
|
||||
FixNameSpaces(s, strlen(s));
|
||||
|
||||
ModelInstanceNames.push_back(s);
|
||||
|
||||
ExtractSingleModel(path);
|
||||
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(fourcc,"MWMO"))
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
char* buf = new char[size];
|
||||
ADT.read(buf, size);
|
||||
char* p = buf;
|
||||
while (p < buf + size)
|
||||
{
|
||||
char* s = GetPlainName(p);
|
||||
FixNameCase(s, strlen(s));
|
||||
FixNameSpaces(s, strlen(s));
|
||||
|
||||
WmoInstanceNames.push_back(s);
|
||||
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
//======================
|
||||
else if (!strcmp(fourcc,"MDDF"))
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
nMDX = (int)size / 36;
|
||||
for (int i=0; i<nMDX; ++i)
|
||||
{
|
||||
uint32 id;
|
||||
ADT.read(&id, 4);
|
||||
ModelInstance inst(ADT, ModelInstanceNames[id].c_str(), map_num, tileX, tileY, dirfile);
|
||||
}
|
||||
|
||||
ModelInstanceNames.clear();
|
||||
}
|
||||
}
|
||||
else if (!strcmp(fourcc,"MODF"))
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
nWMO = (int)size / 64;
|
||||
for (int i=0; i<nWMO; ++i)
|
||||
{
|
||||
uint32 id;
|
||||
ADT.read(&id, 4);
|
||||
WMOInstance inst(ADT, WmoInstanceNames[id].c_str(), map_num, tileX, tileY, dirfile);
|
||||
}
|
||||
|
||||
WmoInstanceNames.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//======================
|
||||
ADT.seek(nextpos);
|
||||
}
|
||||
|
||||
ADT.close();
|
||||
fclose(dirfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
ADTFile::~ADTFile()
|
||||
{
|
||||
ADT.close();
|
||||
}
|
||||
143
src/tools/vmap4_extractor/adtfile.h
Normal file
143
src/tools/vmap4_extractor/adtfile.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef ADT_H
|
||||
#define ADT_H
|
||||
|
||||
#include "mpqfile.h"
|
||||
#include "wmo.h"
|
||||
#include "model.h"
|
||||
|
||||
#define TILESIZE (533.33333f)
|
||||
#define CHUNKSIZE ((TILESIZE) / 16.0f)
|
||||
#define UNITSIZE (CHUNKSIZE / 8.0f)
|
||||
|
||||
class Liquid;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
}svec;
|
||||
|
||||
struct vec
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
};
|
||||
|
||||
struct triangle
|
||||
{
|
||||
vec v[3];
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float v9[16*8+1][16*8+1];
|
||||
float v8[16*8][16*8];
|
||||
}Cell;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double v9[9][9];
|
||||
double v8[8][8];
|
||||
uint16 area_id;
|
||||
//Liquid *lq;
|
||||
float waterlevel[9][9];
|
||||
uint8 flag;
|
||||
}chunk;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
chunk ch[16][16];
|
||||
}mcell;
|
||||
|
||||
struct MapChunkHeader
|
||||
{
|
||||
uint32 flags;
|
||||
uint32 ix;
|
||||
uint32 iy;
|
||||
uint32 nLayers;
|
||||
uint32 nDoodadRefs;
|
||||
uint32 ofsHeight;
|
||||
uint32 ofsNormal;
|
||||
uint32 ofsLayer;
|
||||
uint32 ofsRefs;
|
||||
uint32 ofsAlpha;
|
||||
uint32 sizeAlpha;
|
||||
uint32 ofsShadow;
|
||||
uint32 sizeShadow;
|
||||
uint32 areaid;
|
||||
uint32 nMapObjRefs;
|
||||
uint32 holes;
|
||||
uint16 s1;
|
||||
uint16 s2;
|
||||
uint32 d1;
|
||||
uint32 d2;
|
||||
uint32 d3;
|
||||
uint32 predTex;
|
||||
uint32 nEffectDoodad;
|
||||
uint32 ofsSndEmitters;
|
||||
uint32 nSndEmitters;
|
||||
uint32 ofsLiquid;
|
||||
uint32 sizeLiquid;
|
||||
float zpos;
|
||||
float xpos;
|
||||
float ypos;
|
||||
uint32 textureId;
|
||||
uint32 props;
|
||||
uint32 effectId;
|
||||
};
|
||||
|
||||
|
||||
class ADTFile
|
||||
{
|
||||
private:
|
||||
//size_t mcnk_offsets[256], mcnk_sizes[256];
|
||||
MPQFile ADT;
|
||||
//mcell Mcell;
|
||||
std::string Adtfilename;
|
||||
public:
|
||||
ADTFile(char* filename);
|
||||
~ADTFile();
|
||||
int nWMO;
|
||||
int nMDX;
|
||||
std::vector<std::string> WmoInstanceNames;
|
||||
std::vector<std::string> ModelInstanceNames;
|
||||
bool init(uint32 map_num, uint32 tileX, uint32 tileY);
|
||||
//void LoadMapChunks();
|
||||
|
||||
//uint32 wmo_count;
|
||||
/*
|
||||
const mcell& Getmcell() const
|
||||
{
|
||||
return Mcell;
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
char const* GetPlainName(char const* FileName);
|
||||
char* GetPlainName(char* FileName);
|
||||
char* GetExtension(char* FileName);
|
||||
void FixNameCase(char* name, size_t len);
|
||||
void FixNameSpaces(char* name, size_t len);
|
||||
//void fixMapNamen(char *name, size_t len);
|
||||
|
||||
#endif
|
||||
213
src/tools/vmap4_extractor/dbcfile.cpp
Normal file
213
src/tools/vmap4_extractor/dbcfile.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#include "dbcfile.h"
|
||||
|
||||
DBCFile::DBCFile(char const* file, char const* fmt, bool isdbc /*= false*/)
|
||||
{
|
||||
_file = file;
|
||||
_fmt = fmt;
|
||||
_isDBC = isdbc;
|
||||
recordTable = nullptr;
|
||||
stringTable = nullptr;
|
||||
fieldsOffset = nullptr;
|
||||
|
||||
header.RecordSize = 0;
|
||||
header.RecordCount = 0;
|
||||
header.FieldCount = 0;
|
||||
header.BlockValue = 0;
|
||||
header.Signature = 0;
|
||||
header.Hash = 0;
|
||||
header.Build = 0;
|
||||
header.TimeStamp = 0;
|
||||
header.Min = 0;
|
||||
header.Max = 0;
|
||||
header.Locale = 0;
|
||||
header.ReferenceDataSize = 0;
|
||||
header.MetaFlags = 0;
|
||||
}
|
||||
|
||||
bool DBCFile::open()
|
||||
{
|
||||
if (recordTable)
|
||||
{
|
||||
delete[] recordTable;
|
||||
recordTable = nullptr;
|
||||
}
|
||||
|
||||
FILE* f = fopen(_file, "rb");
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
if (fread(&header.Signature, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&header.RecordCount, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&header.FieldCount, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&header.RecordSize, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&header.BlockValue, sizeof(uint32), 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isDBC)
|
||||
{
|
||||
fread(&header.Hash, sizeof(uint32), 1, f);
|
||||
fread(&header.Build, sizeof(uint32), 1, f);
|
||||
fread(&header.TimeStamp, sizeof(uint32), 1, f);
|
||||
fread(&header.Min, sizeof(uint32), 1, f);
|
||||
fread(&header.Max, sizeof(uint32), 1, f);
|
||||
fread(&header.Locale, sizeof(uint32), 1, f);
|
||||
fread(&header.ReferenceDataSize, sizeof(uint32), 1, f);
|
||||
//fread(&header.MetaFlags, sizeof(uint32), 1, f);
|
||||
}
|
||||
|
||||
recordTable = new unsigned char[header.RecordSize * header.RecordCount + header.BlockValue];
|
||||
stringTable = recordTable + header.RecordSize * header.RecordCount;
|
||||
|
||||
if (fread(recordTable, header.RecordSize * header.RecordCount + header.BlockValue, 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
fieldsOffset = new uint32[header.FieldCount];
|
||||
fieldsOffset[0] = 0;
|
||||
for (uint32 i = 1; i < header.FieldCount; i++)
|
||||
{
|
||||
fieldsOffset[i] = fieldsOffset[i - 1];
|
||||
switch (_fmt[i - 1])
|
||||
{
|
||||
case 'l':
|
||||
fieldsOffset[i] += sizeof(uint64);
|
||||
break;
|
||||
case 'n':
|
||||
case 'i':
|
||||
case 'f':
|
||||
fieldsOffset[i] += sizeof(uint32);
|
||||
break;
|
||||
case 't':
|
||||
fieldsOffset[i] += sizeof(uint16);
|
||||
break;
|
||||
case 'b':
|
||||
fieldsOffset[i] += sizeof(uint8);
|
||||
break;
|
||||
case 's':
|
||||
fieldsOffset[i] += 4/*sizeof(char*)*/; //! WARNING! Size 4
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
DBCFile::~DBCFile()
|
||||
{
|
||||
delete[] recordTable;
|
||||
}
|
||||
|
||||
DBCFile::Record DBCFile::getRecord(size_t id)
|
||||
{
|
||||
assert(recordTable);
|
||||
return Record(*this, recordTable + id * header.RecordSize);
|
||||
}
|
||||
|
||||
float DBCFile::Record::getFloat(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<float*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
uint32 DBCFile::Record::getUInt(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<uint32*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
uint8 DBCFile::Record::getUInt8(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<uint8*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
uint16 DBCFile::Record::getUInt16(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<uint16*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
uint64 DBCFile::Record::getUInt64(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return *reinterpret_cast<uint64*>(offset + file.GetOffset(field));
|
||||
}
|
||||
|
||||
char const* DBCFile::Record::getString(size_t field) const
|
||||
{
|
||||
assert(field < file.header.FieldCount);
|
||||
return reinterpret_cast<char*>(file.stringTable + getUInt(field));
|
||||
}
|
||||
|
||||
size_t DBCFile::getMaxId()
|
||||
{
|
||||
assert(recordTable);
|
||||
|
||||
size_t maxId = 0;
|
||||
for (size_t i = 0; i < getRecordCount(); ++i)
|
||||
if (maxId < getRecord(i).getUInt(0))
|
||||
maxId = getRecord(i).getUInt(0);
|
||||
|
||||
return maxId;
|
||||
}
|
||||
|
||||
DBCFile::Iterator DBCFile::begin()
|
||||
{
|
||||
assert(recordTable);
|
||||
return Iterator(*this, recordTable);
|
||||
}
|
||||
|
||||
DBCFile::Iterator DBCFile::end()
|
||||
{
|
||||
assert(recordTable);
|
||||
return Iterator(*this, stringTable);
|
||||
}
|
||||
111
src/tools/vmap4_extractor/dbcfile.h
Normal file
111
src/tools/vmap4_extractor/dbcfile.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef DBCFILE_H
|
||||
#define DBCFILE_H
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
#include "Define.h"
|
||||
|
||||
class DBCFile
|
||||
{
|
||||
public:
|
||||
DBCFile(char const* file, char const* fmt, bool isdbc = false);
|
||||
~DBCFile();
|
||||
|
||||
bool open();
|
||||
|
||||
class Iterator;
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
float getFloat(size_t field) const;
|
||||
uint32 getUInt(size_t field) const;
|
||||
uint8 getUInt8(size_t field) const;
|
||||
uint16 getUInt16(size_t field) const;
|
||||
uint64 getUInt64(size_t field) const;
|
||||
char const* getString(size_t field) const;
|
||||
|
||||
private:
|
||||
Record(DBCFile& file, unsigned char* offset) : file(file), offset(offset) { }
|
||||
DBCFile& file;
|
||||
unsigned char* offset;
|
||||
|
||||
friend class DBCFile;
|
||||
friend class DBCFile::Iterator;
|
||||
|
||||
Record& operator=(Record const& right);
|
||||
};
|
||||
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
Iterator(DBCFile &file, unsigned char* offset) : record(file, offset) { }
|
||||
Iterator& operator++()
|
||||
{
|
||||
record.offset += record.file.header.RecordSize;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Record const& operator*() const { return record; }
|
||||
Record const* operator->() const { return &record; }
|
||||
bool operator==(Iterator const& b) const { return record.offset == b.record.offset; }
|
||||
bool operator!=(Iterator const& b) const { return record.offset != b.record.offset; }
|
||||
|
||||
private:
|
||||
Record record;
|
||||
Iterator& operator=(Iterator const& right);
|
||||
};
|
||||
|
||||
Record getRecord(size_t id);
|
||||
uint32 GetOffset(size_t id) const { return (fieldsOffset != nullptr && id < header.FieldCount) ? fieldsOffset[id] : 0; }
|
||||
Iterator begin();
|
||||
Iterator end();
|
||||
size_t getRecordCount() const { return header.RecordCount; }
|
||||
size_t getFieldCount() const { return header.FieldCount; }
|
||||
size_t getMaxId();
|
||||
|
||||
private:
|
||||
uint32* fieldsOffset;
|
||||
char const* _file;
|
||||
unsigned char* recordTable;
|
||||
unsigned char* stringTable;
|
||||
char const* _fmt;
|
||||
bool _isDBC;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 Signature;
|
||||
uint32 RecordCount;
|
||||
uint32 FieldCount;
|
||||
uint32 RecordSize;
|
||||
uint32 BlockValue;
|
||||
uint32 Hash;
|
||||
uint32 Build;
|
||||
uint32 TimeStamp;
|
||||
uint32 Min;
|
||||
uint32 Max;
|
||||
uint32 Locale;
|
||||
uint32 ReferenceDataSize;
|
||||
uint32 MetaFlags;
|
||||
} header;
|
||||
};
|
||||
|
||||
#endif
|
||||
141
src/tools/vmap4_extractor/gameobject_extract.cpp
Normal file
141
src/tools/vmap4_extractor/gameobject_extract.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "model.h"
|
||||
#include "dbcfile.h"
|
||||
#include "adtfile.h"
|
||||
#include "vmapexport.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
bool ExtractSingleModel(std::string& fname)
|
||||
{
|
||||
if (fname.substr(fname.length() - 4, 4) == ".mdx")
|
||||
{
|
||||
fname.erase(fname.length() - 2, 2);
|
||||
fname.append("2");
|
||||
}
|
||||
|
||||
std::string originalName = fname;
|
||||
|
||||
char* name = GetPlainName((char*)fname.c_str());
|
||||
FixNameCase(name, strlen(name));
|
||||
FixNameSpaces(name, strlen(name));
|
||||
|
||||
std::string output(szWorkDirWmo);
|
||||
output += "/";
|
||||
output += name;
|
||||
|
||||
if (FileExists(output.c_str()))
|
||||
return true;
|
||||
|
||||
Model mdl(originalName);
|
||||
if (!mdl.open())
|
||||
return false;
|
||||
|
||||
return mdl.ConvertToVMAPModel(output.c_str());
|
||||
}
|
||||
|
||||
void ExtractGameobjectModels()
|
||||
{
|
||||
printf("Extracting GameObject models...");
|
||||
DBCFile dbc("DBFilesClient\\GameObjectDisplayInfo.db2", "nifffffffft");
|
||||
if(!dbc.open())
|
||||
{
|
||||
printf("Fatal error: Invalid GameObjectDisplayInfo.db2 file format!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
DBCFile fileData("DBFilesClient\\FileDataComplete.dbc", "nss", true);
|
||||
if (!fileData.open())
|
||||
{
|
||||
printf("Fatal error: Invalid FileDataComplete.dbc file format!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::string basepath = szWorkDirWmo;
|
||||
basepath += "/";
|
||||
std::string path;
|
||||
|
||||
std::string modelListPath = basepath + "temp_gameobject_models";
|
||||
FILE* modelList = fopen(modelListPath.c_str(), "wb");
|
||||
if (!modelList)
|
||||
{
|
||||
printf("Fatal error: Could not open file %s\n", modelListPath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
size_t maxFileId = fileData.getMaxId() + 1;
|
||||
uint32* fileDataIndex = new uint32[maxFileId];
|
||||
memset(fileDataIndex, 0, maxFileId * sizeof(uint32));
|
||||
|
||||
for (size_t i = 0; i < fileData.getRecordCount(); ++i)
|
||||
fileDataIndex[fileData.getRecord(i).getUInt(0)] = i;
|
||||
|
||||
for (DBCFile::Iterator it = dbc.begin(); it != dbc.end(); ++it)
|
||||
{
|
||||
uint32 fileId = it->getUInt(0);
|
||||
if (!fileId)
|
||||
continue;
|
||||
|
||||
uint32 fileIndex = fileDataIndex[fileId];
|
||||
if (!fileIndex)
|
||||
continue;
|
||||
|
||||
std::string filepath = fileData.getRecord(fileIndex).getString(1);
|
||||
std::string filename = fileData.getRecord(fileIndex).getString(2);
|
||||
|
||||
path = filepath + filename;
|
||||
if (path.length() < 4)
|
||||
continue;
|
||||
|
||||
FixNameCase((char*)path.c_str(), path.size());
|
||||
char* name = GetPlainName((char*)path.c_str());
|
||||
FixNameSpaces(name, strlen(name));
|
||||
|
||||
char* ch_ext = GetExtension(name);
|
||||
if (!ch_ext)
|
||||
continue;
|
||||
|
||||
strToLower(ch_ext);
|
||||
|
||||
bool result = false;
|
||||
if (!strcmp(ch_ext, ".wmo"))
|
||||
result = ExtractSingleWmo(path);
|
||||
else if (!strcmp(ch_ext, ".mdl")) // TODO: extract .mdl files, if needed
|
||||
continue;
|
||||
else if (!strcmp(ch_ext, ".mdx") || !strcmp(ch_ext, ".m2"))
|
||||
result = ExtractSingleModel(path);
|
||||
|
||||
if (result)
|
||||
{
|
||||
uint32 displayID = it->getUInt(0);
|
||||
uint32 pathLength = strlen(name);
|
||||
fwrite(&displayID, sizeof(uint32), 1, modelList);
|
||||
fwrite(&pathLength, sizeof(uint32), 1, modelList);
|
||||
fwrite(name, sizeof(char), pathLength, modelList);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(modelList);
|
||||
|
||||
delete[] fileDataIndex;
|
||||
|
||||
printf("Done!\n");
|
||||
}
|
||||
260
src/tools/vmap4_extractor/model.cpp
Normal file
260
src/tools/vmap4_extractor/model.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "model.h"
|
||||
#include "wmo.h"
|
||||
#include "mpqfile.h"
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0)
|
||||
{
|
||||
memset(&header, 0, sizeof(header));
|
||||
}
|
||||
|
||||
bool Model::open()
|
||||
{
|
||||
MPQFile f(filename.c_str());
|
||||
|
||||
if (f.isEof())
|
||||
{
|
||||
f.close();
|
||||
// Do not show this error on console to avoid confusion, the extractor can continue working even if some models fail to load
|
||||
//printf("Error loading model %s\n", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
_unload();
|
||||
|
||||
char fourcc[5];
|
||||
uint32 size;
|
||||
|
||||
while (true)
|
||||
{
|
||||
f.read(fourcc, 4);
|
||||
f.read(&size, 4);
|
||||
flipcc(fourcc);
|
||||
fourcc[4] = 0;
|
||||
|
||||
size_t nextpos = f.getPos() + size;
|
||||
|
||||
if (!size)
|
||||
break;
|
||||
|
||||
char *buf = new char[size];
|
||||
f.read(buf, size);
|
||||
|
||||
if (!strcmp(fourcc, "12DM") || !strcmp(fourcc, "MD21"))
|
||||
{
|
||||
memcpy(&header, buf, sizeof(ModelHeader));
|
||||
|
||||
//printf("\n ADDDDDDDDD -- %s ---- %u\n", filename.c_str(), header.nBoundingTriangles);
|
||||
|
||||
if (header.nBoundingTriangles > 0)
|
||||
{
|
||||
vertices = new Vec3D[header.nBoundingVertices];
|
||||
memcpy(vertices, &(buf[header.ofsBoundingVertices]), header.nBoundingVertices * 12);
|
||||
for (uint32 i = 0; i<header.nBoundingVertices; i++)
|
||||
vertices[i] = fixCoordSystem(vertices[i]);
|
||||
|
||||
|
||||
indices = new uint16[header.nBoundingTriangles];
|
||||
memcpy(indices, &buf[header.ofsBoundingTriangles], header.nBoundingTriangles * 2);
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
f.close();
|
||||
return false;
|
||||
|
||||
}
|
||||
else if (strcmp(fourcc, "SFID") && strcmp(fourcc, "DIFS"))
|
||||
printf("\n------>%u -- %s -- %s\n", nextpos, filename.c_str(), fourcc);
|
||||
f.seek((int) nextpos);
|
||||
}
|
||||
|
||||
//memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
|
||||
//if (header.nBoundingTriangles > 0)
|
||||
//{
|
||||
// f.seek(0);
|
||||
// f.seekRelative(header.ofsBoundingVertices);
|
||||
// vertices = new Vec3D[header.nBoundingVertices];
|
||||
// f.read(vertices,header.nBoundingVertices*12);
|
||||
// for (uint32 i=0; i<header.nBoundingVertices; i++)
|
||||
// vertices[i] = fixCoordSystem(vertices[i]);
|
||||
// f.seek(0);
|
||||
// f.seekRelative(header.ofsBoundingTriangles);
|
||||
// indices = new uint16[header.nBoundingTriangles];
|
||||
// f.read(indices,header.nBoundingTriangles*2);
|
||||
// f.close();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// //printf("not included %s\n", filename.c_str());
|
||||
// f.close();
|
||||
// return false;
|
||||
//}
|
||||
f.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Model::ConvertToVMAPModel(const char * outfilename)
|
||||
{
|
||||
int N[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
FILE* output=fopen(outfilename, "wb");
|
||||
if (!output)
|
||||
{
|
||||
printf("Can't create the output file '%s'\n",outfilename);
|
||||
return false;
|
||||
}
|
||||
fwrite(szRawVMAPMagic, 8, 1, output);
|
||||
uint32 nVertices = header.nBoundingVertices;
|
||||
fwrite(&nVertices, sizeof(int), 1, output);
|
||||
uint32 nofgroups = 1;
|
||||
fwrite(&nofgroups,sizeof(uint32), 1, output);
|
||||
fwrite(N,4*3,1,output);// rootwmoid, flags, groupid
|
||||
fwrite(N,sizeof(float),3*2,output);//bbox, only needed for WMO currently
|
||||
fwrite(N,4,1,output);// liquidflags
|
||||
fwrite("GRP ",4,1,output);
|
||||
uint32 branches = 1;
|
||||
int wsize;
|
||||
wsize = sizeof(branches) + sizeof(uint32) * branches;
|
||||
fwrite(&wsize, sizeof(int), 1, output);
|
||||
fwrite(&branches,sizeof(branches), 1, output);
|
||||
uint32 nIndexes = header.nBoundingTriangles;
|
||||
fwrite(&nIndexes,sizeof(uint32), 1, output);
|
||||
fwrite("INDX",4, 1, output);
|
||||
wsize = sizeof(uint32) + sizeof(unsigned short) * nIndexes;
|
||||
fwrite(&wsize, sizeof(int), 1, output);
|
||||
fwrite(&nIndexes, sizeof(uint32), 1, output);
|
||||
if (nIndexes > 0)
|
||||
{
|
||||
for (uint32 i = 0; i < nIndexes; ++i)
|
||||
{
|
||||
if ((i % 3) - 1 == 0 && i + 1 < nIndexes)
|
||||
{
|
||||
uint16 tmp = indices[i];
|
||||
indices[i] = indices[i + 1];
|
||||
indices[i + 1] = tmp;
|
||||
}
|
||||
}
|
||||
fwrite(indices, sizeof(unsigned short), nIndexes, output);
|
||||
}
|
||||
|
||||
fwrite("VERT", 4, 1, output);
|
||||
wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
|
||||
fwrite(&wsize, sizeof(int), 1, output);
|
||||
fwrite(&nVertices, sizeof(int), 1, output);
|
||||
if (nVertices >0)
|
||||
{
|
||||
for (uint32 vpos = 0; vpos < nVertices; ++vpos)
|
||||
{
|
||||
float tmp = vertices[vpos].y;
|
||||
vertices[vpos].y = -vertices[vpos].z;
|
||||
vertices[vpos].z = tmp;
|
||||
}
|
||||
|
||||
fwrite(vertices, sizeof(float)*3, nVertices, output);
|
||||
}
|
||||
|
||||
fclose(output);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Vec3D fixCoordSystem(Vec3D v)
|
||||
{
|
||||
return Vec3D(v.x, v.z, -v.y);
|
||||
}
|
||||
|
||||
Vec3D fixCoordSystem2(Vec3D v)
|
||||
{
|
||||
return Vec3D(v.x, v.z, v.y);
|
||||
}
|
||||
|
||||
ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile)
|
||||
: id(0), scale(0), flags(0)
|
||||
{
|
||||
float ff[3];
|
||||
f.read(&id, 4);
|
||||
f.read(ff, 12);
|
||||
pos = fixCoords(Vec3D(ff[0], ff[1], ff[2]));
|
||||
f.read(ff, 12);
|
||||
rot = Vec3D(ff[0], ff[1], ff[2]);
|
||||
f.read(&scale, 2);
|
||||
f.read(&flags, 2);
|
||||
// scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
|
||||
sc = scale / 1024.0f;
|
||||
|
||||
char tempname[512];
|
||||
sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName);
|
||||
FILE* input = fopen(tempname, "r+b");
|
||||
|
||||
if (!input)
|
||||
{
|
||||
// printf("ModelInstance::ModelInstance couldn't open %s\n", tempname);
|
||||
//system("pause");
|
||||
return;
|
||||
}
|
||||
// printf("ModelInstance::open %s\n", tempname);
|
||||
|
||||
fseek(input, 8, SEEK_SET); // get the correct no of vertices
|
||||
int nVertices;
|
||||
int count = fread(&nVertices, sizeof (int), 1, input);
|
||||
fclose(input);
|
||||
|
||||
if (count != 1 || nVertices == 0)
|
||||
return;
|
||||
|
||||
uint16 adtId = 0;// not used for models
|
||||
uint32 flags = MOD_M2;
|
||||
if (tileX == 65 && tileY == 65)
|
||||
flags |= MOD_WORLDSPAWN;
|
||||
|
||||
//write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name
|
||||
fwrite(&mapID, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&tileX, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&tileY, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&flags, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&adtId, sizeof(uint16), 1, pDirfile);
|
||||
fwrite(&id, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&pos, sizeof(float), 3, pDirfile);
|
||||
fwrite(&rot, sizeof(float), 3, pDirfile);
|
||||
fwrite(&sc, sizeof(float), 1, pDirfile);
|
||||
uint32 nlen=strlen(ModelInstName);
|
||||
fwrite(&nlen, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(ModelInstName, sizeof(char), nlen, pDirfile);
|
||||
|
||||
/* int realx1 = (int) ((float) pos.x / 533.333333f);
|
||||
int realy1 = (int) ((float) pos.z / 533.333333f);
|
||||
int realx2 = (int) ((float) pos.x / 533.333333f);
|
||||
int realy2 = (int) ((float) pos.z / 533.333333f);
|
||||
|
||||
fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
|
||||
MapName,
|
||||
ModelInstName,
|
||||
(float) pos.x, (float) pos.y, (float) pos.z,
|
||||
(float) rot.x, (float) rot.y, (float) rot.z,
|
||||
sc,
|
||||
nVertices,
|
||||
realx1, realy1,
|
||||
realx2, realy2
|
||||
); */
|
||||
}
|
||||
66
src/tools/vmap4_extractor/model.h
Normal file
66
src/tools/vmap4_extractor/model.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
#include "vec3d.h"
|
||||
#include "modelheaders.h"
|
||||
#include <vector>
|
||||
|
||||
class MPQFile;
|
||||
|
||||
Vec3D fixCoordSystem(Vec3D v);
|
||||
|
||||
class Model
|
||||
{
|
||||
private:
|
||||
void _unload()
|
||||
{
|
||||
delete[] vertices;
|
||||
delete[] indices;
|
||||
vertices = NULL;
|
||||
indices = NULL;
|
||||
}
|
||||
std::string filename;
|
||||
public:
|
||||
ModelHeader header;
|
||||
Vec3D* vertices;
|
||||
uint16* indices;
|
||||
|
||||
bool open();
|
||||
bool ConvertToVMAPModel(char const* outfilename);
|
||||
|
||||
Model(std::string& filename);
|
||||
~Model() { _unload(); }
|
||||
};
|
||||
|
||||
class ModelInstance
|
||||
{
|
||||
public:
|
||||
uint32 id;
|
||||
Vec3D pos, rot;
|
||||
uint16 scale, flags;
|
||||
float sc;
|
||||
|
||||
ModelInstance() : id(0), scale(0), flags(0), sc(0.0f) {}
|
||||
ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
94
src/tools/vmap4_extractor/modelheaders.h
Normal file
94
src/tools/vmap4_extractor/modelheaders.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MODELHEADERS_H
|
||||
#define MODELHEADERS_H
|
||||
|
||||
#include "mpqfile.h" // integer typedefs
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
struct ModelHeader
|
||||
{
|
||||
char id[4];
|
||||
uint8 version[4];
|
||||
uint32 nameLength;
|
||||
uint32 nameOfs;
|
||||
uint32 type;
|
||||
uint32 nGlobalSequences;
|
||||
uint32 ofsGlobalSequences;
|
||||
uint32 nAnimations;
|
||||
uint32 ofsAnimations;
|
||||
uint32 nAnimationLookup;
|
||||
uint32 ofsAnimationLookup;
|
||||
uint32 nBones;
|
||||
uint32 ofsBones;
|
||||
uint32 nKeyBoneLookup;
|
||||
uint32 ofsKeyBoneLookup;
|
||||
uint32 nVertices;
|
||||
uint32 ofsVertices;
|
||||
uint32 nViews;
|
||||
uint32 nColors;
|
||||
uint32 ofsColors;
|
||||
uint32 nTextures;
|
||||
uint32 ofsTextures;
|
||||
uint32 nTransparency;
|
||||
uint32 ofsTransparency;
|
||||
uint32 nTextureanimations;
|
||||
uint32 ofsTextureanimations;
|
||||
uint32 nTexReplace;
|
||||
uint32 ofsTexReplace;
|
||||
uint32 nRenderFlags;
|
||||
uint32 ofsRenderFlags;
|
||||
uint32 nBoneLookupTable;
|
||||
uint32 ofsBoneLookupTable;
|
||||
uint32 nTexLookup;
|
||||
uint32 ofsTexLookup;
|
||||
uint32 nTexUnits;
|
||||
uint32 ofsTexUnits;
|
||||
uint32 nTransLookup;
|
||||
uint32 ofsTransLookup;
|
||||
uint32 nTexAnimLookup;
|
||||
uint32 ofsTexAnimLookup;
|
||||
float floats[14];
|
||||
uint32 nBoundingTriangles;
|
||||
uint32 ofsBoundingTriangles;
|
||||
uint32 nBoundingVertices;
|
||||
uint32 ofsBoundingVertices;
|
||||
uint32 nBoundingNormals;
|
||||
uint32 ofsBoundingNormals;
|
||||
uint32 nAttachments;
|
||||
uint32 ofsAttachments;
|
||||
uint32 nAttachLookup;
|
||||
uint32 ofsAttachLookup;
|
||||
uint32 nAttachments_2;
|
||||
uint32 ofsAttachments_2;
|
||||
uint32 nLights;
|
||||
uint32 ofsLights;
|
||||
uint32 nCameras;
|
||||
uint32 ofsCameras;
|
||||
uint32 nCameraLookup;
|
||||
uint32 ofsCameraLookup;
|
||||
uint32 nRibbonEmitters;
|
||||
uint32 ofsRibbonEmitters;
|
||||
uint32 nParticleEmitters;
|
||||
uint32 ofsParticleEmitters;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
79
src/tools/vmap4_extractor/mpqfile.cpp
Normal file
79
src/tools/vmap4_extractor/mpqfile.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "mpqfile.h"
|
||||
#include <deque>
|
||||
#include <cstdio>
|
||||
|
||||
MPQFile::MPQFile(const char* filename) :
|
||||
eof(false),
|
||||
buffer(0),
|
||||
pointer(0),
|
||||
size(0)
|
||||
{
|
||||
FILE* f = fopen(filename, "rb");
|
||||
if (!f)
|
||||
{
|
||||
// fprintf(stderr, "Can't open %s\n", filename);
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t sizeTemp = ftell(f);
|
||||
size = sizeTemp;
|
||||
rewind(f);
|
||||
|
||||
if (size <= 1)
|
||||
{
|
||||
fprintf(stderr, "Can't open %s, size = %u!\n", filename, uint32(size));
|
||||
fclose(f);
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = new char[size];
|
||||
if (fread(buffer, sizeTemp, 1, f) != 1)
|
||||
{
|
||||
fprintf(stderr, "Can't read %s, size=%u!\n", filename, uint32(size));
|
||||
fclose(f);
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
size = sizeTemp;
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
size_t MPQFile::read(void* dest, size_t bytes)
|
||||
{
|
||||
if (eof) return 0;
|
||||
|
||||
size_t rpos = pointer + bytes;
|
||||
if (rpos > size) {
|
||||
bytes = size - pointer;
|
||||
eof = true;
|
||||
}
|
||||
|
||||
memcpy(dest, &(buffer[pointer]), bytes);
|
||||
|
||||
pointer = rpos;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void MPQFile::seek(int offset)
|
||||
{
|
||||
pointer = offset;
|
||||
eof = (pointer >= size);
|
||||
}
|
||||
|
||||
void MPQFile::seekRelative(int offset)
|
||||
{
|
||||
pointer += offset;
|
||||
eof = (pointer >= size);
|
||||
}
|
||||
|
||||
void MPQFile::close()
|
||||
{
|
||||
if (buffer) delete[] buffer;
|
||||
buffer = 0;
|
||||
eof = true;
|
||||
}
|
||||
67
src/tools/vmap4_extractor/mpqfile.h
Normal file
67
src/tools/vmap4_extractor/mpqfile.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS // fuck the police^Wwarnings
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#ifndef MPQ_H
|
||||
#define MPQ_H
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <deque>
|
||||
#include <cstdint>
|
||||
|
||||
typedef int64_t int64;
|
||||
typedef int32_t int32;
|
||||
typedef int16_t int16;
|
||||
typedef int8_t int8;
|
||||
typedef uint64_t uint64;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint8_t uint8;
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h> // mainly only HANDLE definition is required
|
||||
#else
|
||||
int GetLastError();
|
||||
#endif
|
||||
|
||||
class MPQFile
|
||||
{
|
||||
//MPQHANDLE handle;
|
||||
bool eof;
|
||||
char *buffer;
|
||||
size_t pointer,size;
|
||||
|
||||
// disable copying
|
||||
MPQFile(const MPQFile &f);
|
||||
void operator=(const MPQFile &f);
|
||||
|
||||
public:
|
||||
MPQFile(const char* filename); // filenames are not case sensitive
|
||||
~MPQFile() { close(); }
|
||||
size_t read(void* dest, size_t bytes);
|
||||
size_t getSize() { return size; }
|
||||
size_t getPos() { return pointer; }
|
||||
char* getBuffer() { return buffer; }
|
||||
char* getPointer() { return buffer + pointer; }
|
||||
bool isEof() { return eof; }
|
||||
void seek(int offset);
|
||||
void seekRelative(int offset);
|
||||
void close();
|
||||
};
|
||||
|
||||
inline void flipcc(char *fcc)
|
||||
{
|
||||
char t;
|
||||
t=fcc[0];
|
||||
fcc[0]=fcc[3];
|
||||
fcc[3]=t;
|
||||
t=fcc[1];
|
||||
fcc[1]=fcc[2];
|
||||
fcc[2]=t;
|
||||
}
|
||||
|
||||
#endif
|
||||
248
src/tools/vmap4_extractor/vec3d.h
Normal file
248
src/tools/vmap4_extractor/vec3d.h
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef VEC3D_H
|
||||
#define VEC3D_H
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
class Vec3D
|
||||
{
|
||||
public:
|
||||
float x,y,z;
|
||||
|
||||
Vec3D(float x0 = 0.0f, float y0 = 0.0f, float z0 = 0.0f) : x(x0), y(y0), z(z0) {}
|
||||
|
||||
Vec3D(const Vec3D& v) : x(v.x), y(v.y), z(v.z) {}
|
||||
|
||||
Vec3D& operator= (const Vec3D &v) {
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3D operator+ (const Vec3D &v) const
|
||||
{
|
||||
Vec3D r(x+v.x,y+v.y,z+v.z);
|
||||
return r;
|
||||
}
|
||||
|
||||
Vec3D operator- (const Vec3D &v) const
|
||||
{
|
||||
Vec3D r(x-v.x,y-v.y,z-v.z);
|
||||
return r;
|
||||
}
|
||||
|
||||
float operator* (const Vec3D &v) const
|
||||
{
|
||||
return x*v.x + y*v.y + z*v.z;
|
||||
}
|
||||
|
||||
Vec3D operator* (float d) const
|
||||
{
|
||||
Vec3D r(x*d,y*d,z*d);
|
||||
return r;
|
||||
}
|
||||
|
||||
friend Vec3D operator* (float d, const Vec3D& v)
|
||||
{
|
||||
return v * d;
|
||||
}
|
||||
|
||||
Vec3D operator% (const Vec3D &v) const
|
||||
{
|
||||
Vec3D r(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x);
|
||||
return r;
|
||||
}
|
||||
|
||||
Vec3D& operator+= (const Vec3D &v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
z += v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3D& operator-= (const Vec3D &v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
z -= v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3D& operator*= (float d)
|
||||
{
|
||||
x *= d;
|
||||
y *= d;
|
||||
z *= d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float lengthSquared() const
|
||||
{
|
||||
return x*x+y*y+z*z;
|
||||
}
|
||||
|
||||
float length() const
|
||||
{
|
||||
return std::sqrt(x*x+y*y+z*z);
|
||||
}
|
||||
|
||||
Vec3D& normalize()
|
||||
{
|
||||
this->operator*= (1.0f/length());
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec3D operator~ () const
|
||||
{
|
||||
Vec3D r(*this);
|
||||
r.normalize();
|
||||
return r;
|
||||
}
|
||||
|
||||
friend std::istream& operator>>(std::istream& in, Vec3D& v)
|
||||
{
|
||||
in >> v.x >> v.y >> v.z;
|
||||
return in;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, const Vec3D& v)
|
||||
{
|
||||
out << v.x << " " << v.y << " " << v.z;
|
||||
return out;
|
||||
}
|
||||
|
||||
operator float*()
|
||||
{
|
||||
return (float*)this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Vec2D
|
||||
{
|
||||
public:
|
||||
float x,y;
|
||||
|
||||
Vec2D(float x0 = 0.0f, float y0 = 0.0f) : x(x0), y(y0) {}
|
||||
|
||||
Vec2D(const Vec2D& v) : x(v.x), y(v.y) {}
|
||||
|
||||
Vec2D& operator= (const Vec2D &v) {
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2D operator+ (const Vec2D &v) const
|
||||
{
|
||||
Vec2D r(x+v.x,y+v.y);
|
||||
return r;
|
||||
}
|
||||
|
||||
Vec2D operator- (const Vec2D &v) const
|
||||
{
|
||||
Vec2D r(x-v.x,y-v.y);
|
||||
return r;
|
||||
}
|
||||
|
||||
float operator* (const Vec2D &v) const
|
||||
{
|
||||
return x*v.x + y*v.y;
|
||||
}
|
||||
|
||||
Vec2D operator* (float d) const
|
||||
{
|
||||
Vec2D r(x*d,y*d);
|
||||
return r;
|
||||
}
|
||||
|
||||
friend Vec2D operator* (float d, const Vec2D& v)
|
||||
{
|
||||
return v * d;
|
||||
}
|
||||
|
||||
Vec2D& operator+= (const Vec2D &v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2D& operator-= (const Vec2D &v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2D& operator*= (float d)
|
||||
{
|
||||
x *= d;
|
||||
y *= d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float lengthSquared() const
|
||||
{
|
||||
return x*x+y*y;
|
||||
}
|
||||
|
||||
float length() const
|
||||
{
|
||||
return std::sqrt(x*x+y*y);
|
||||
}
|
||||
|
||||
Vec2D& normalize()
|
||||
{
|
||||
this->operator*= (1.0f/length());
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2D operator~ () const
|
||||
{
|
||||
Vec2D r(*this);
|
||||
r.normalize();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
friend std::istream& operator>>(std::istream& in, Vec2D& v)
|
||||
{
|
||||
in >> v.x >> v.y;
|
||||
return in;
|
||||
}
|
||||
|
||||
operator float*()
|
||||
{
|
||||
return (float*)this;
|
||||
}
|
||||
};
|
||||
|
||||
inline void rotate(float x0, float y0, float *x, float *y, float angle)
|
||||
{
|
||||
float xa = *x - x0, ya = *y - y0;
|
||||
*x = xa*cosf(angle) - ya*sinf(angle) + x0;
|
||||
*y = xa*sinf(angle) + ya*cosf(angle) + y0;
|
||||
}
|
||||
|
||||
#endif
|
||||
417
src/tools/vmap4_extractor/vmapexport.cpp
Normal file
417
src/tools/vmap4_extractor/vmapexport.cpp
Normal file
@@ -0,0 +1,417 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <sys/stat.h>
|
||||
#include <direct.h>
|
||||
#define mkdir _mkdir
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#define ERROR_PATH_NOT_FOUND ERROR_FILE_NOT_FOUND
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
//From Extractor
|
||||
#include "adtfile.h"
|
||||
#include "wdtfile.h"
|
||||
#include "dbcfile.h"
|
||||
#include "wmo.h"
|
||||
#include "Common.h"
|
||||
#include "vmapexport.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[64];
|
||||
unsigned int id;
|
||||
}map_id;
|
||||
|
||||
map_id * map_ids;
|
||||
uint16 *LiqType = 0;
|
||||
uint32 map_count;
|
||||
char output_path[128] = ".";
|
||||
char input_path[1024] = ".";
|
||||
bool preciseVectorData = false;
|
||||
|
||||
// Constants
|
||||
|
||||
//static const char * szWorkDirMaps = ".\\Maps";
|
||||
const char* szWorkDirWmo = "./Buildings";
|
||||
const char* szRawVMAPMagic = "VMAP043";
|
||||
|
||||
// Local testing functions
|
||||
|
||||
bool FileExists(const char* file)
|
||||
{
|
||||
if (FILE* n = fopen(file, "rb"))
|
||||
{
|
||||
fclose(n);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void strToLower(char* str)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
*str = tolower(*str);
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
// copied from contrib/extractor/System.cpp
|
||||
void LoadLiquidTypeDB2Data()
|
||||
{
|
||||
printf("Read LiquidType.db2 file...");
|
||||
DBCFile dbc("DBFilesClient\\LiquidType.db2", "nsifffffssssssiiffffffffffffffffffiiiittbbbbbbbbbbi");
|
||||
if (!dbc.open())
|
||||
{
|
||||
printf("Fatal error: Invalid LiquidType.db2 file format!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
size_t LiqType_count = dbc.getRecordCount();
|
||||
size_t LiqType_maxid = dbc.getRecord(LiqType_count - 1).getUInt(0);
|
||||
LiqType = new uint16[LiqType_maxid + 1];
|
||||
memset(LiqType, 0xff, (LiqType_maxid + 1) * sizeof(uint16));
|
||||
|
||||
for (uint32 x = 0; x < LiqType_count; ++x)
|
||||
LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt8(40);
|
||||
|
||||
printf("Done! (%u LiqTypes loaded)\n", (unsigned int)LiqType_count);
|
||||
}
|
||||
|
||||
bool ExtractWmo()
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
std::ifstream wmoList("wmo_list.txt");
|
||||
if (!wmoList)
|
||||
{
|
||||
printf("\nUnable to open wmo_list.txt! Nothing extracted.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<std::string> wmos;
|
||||
for (;;)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(wmoList, str);
|
||||
if (str.empty())
|
||||
break;
|
||||
|
||||
wmos.insert(std::move(str));
|
||||
}
|
||||
|
||||
for (std::string str : wmos)
|
||||
success &= ExtractSingleWmo(str);
|
||||
|
||||
if (success)
|
||||
printf("\nExtract wmo complete (No (fatal) errors)\n");
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ExtractSingleWmo(std::string& fname)
|
||||
{
|
||||
// Copy files from archive
|
||||
|
||||
char szLocalFile[1024];
|
||||
const char * plain_name = GetPlainName(fname.c_str());
|
||||
sprintf(szLocalFile, "%s/%s", szWorkDirWmo, plain_name);
|
||||
FixNameCase(szLocalFile, strlen(szLocalFile));
|
||||
|
||||
if (FileExists(szLocalFile))
|
||||
return true;
|
||||
|
||||
int p = 0;
|
||||
// Select root wmo files
|
||||
char const* rchr = strrchr(plain_name, '_');
|
||||
if (rchr != NULL)
|
||||
{
|
||||
char cpy[4];
|
||||
memcpy(cpy, rchr, 4);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
int m = cpy[i];
|
||||
if (isdigit(m))
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (p == 3)
|
||||
return true;
|
||||
|
||||
bool file_ok = true;
|
||||
std::cout << "Extracting " << fname << std::endl;
|
||||
WMORoot froot(fname);
|
||||
if (!froot.open())
|
||||
{
|
||||
printf("Couldn't open RootWmo!!!\n");
|
||||
return true;
|
||||
}
|
||||
FILE *output = fopen(szLocalFile, "wb");
|
||||
if (!output)
|
||||
{
|
||||
printf("couldn't open %s for writing!\n", szLocalFile);
|
||||
return false;
|
||||
}
|
||||
froot.ConvertToVMAPRootWmo(output);
|
||||
int Wmo_nVertices = 0;
|
||||
//printf("root has %d groups\n", froot->nGroups);
|
||||
if (froot.nGroups != 0)
|
||||
{
|
||||
for (uint32 i = 0; i < froot.nGroups; ++i)
|
||||
{
|
||||
char temp[1024];
|
||||
strncpy(temp, fname.c_str(), 1024);
|
||||
temp[fname.length() - 4] = 0;
|
||||
char groupFileName[1024];
|
||||
sprintf(groupFileName, "%s_%03u.wmo", temp, i);
|
||||
//printf("Trying to open groupfile %s\n",groupFileName);
|
||||
|
||||
std::string s = groupFileName;
|
||||
WMOGroup fgroup(s);
|
||||
if (!fgroup.open())
|
||||
{
|
||||
printf("Could not open all Group file for: %s\n", plain_name);
|
||||
file_ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Wmo_nVertices += fgroup.ConvertToVMAPGroupWmo(output, &froot, preciseVectorData);
|
||||
}
|
||||
}
|
||||
|
||||
fseek(output, 8, SEEK_SET); // store the correct no of vertices
|
||||
fwrite(&Wmo_nVertices, sizeof(int), 1, output);
|
||||
fclose(output);
|
||||
|
||||
// Delete the extracted file in the case of an error
|
||||
if (!file_ok)
|
||||
remove(szLocalFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParsMapFiles()
|
||||
{
|
||||
char fn[512];
|
||||
//char id_filename[64];
|
||||
char id[10];
|
||||
for (unsigned int i = 0; i < map_count; ++i)
|
||||
{
|
||||
sprintf(id, "%04u", map_ids[i].id);
|
||||
sprintf(fn, "World\\Maps\\%s\\%s.wdt", map_ids[i].name, map_ids[i].name);
|
||||
WDTFile WDT(fn, map_ids[i].name);
|
||||
if (WDT.init(id, map_ids[i].id))
|
||||
{
|
||||
printf("Processing Map %u\n[", map_ids[i].id);
|
||||
for (int x = 0; x < 64; ++x)
|
||||
{
|
||||
for (int y = 0; y < 64; ++y)
|
||||
{
|
||||
if (ADTFile *ADT = WDT.GetMap(x, y))
|
||||
{
|
||||
//sprintf(id_filename,"%02u %02u %03u",x,y,map_ids[i].id);//!!!!!!!!!
|
||||
ADT->init(map_ids[i].id, x, y);
|
||||
delete ADT;
|
||||
}
|
||||
}
|
||||
printf("#");
|
||||
fflush(stdout);
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getGamePath()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
strcpy(input_path, "Data\\");
|
||||
#else
|
||||
strcpy(input_path,"Data/");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool processArgv(int argc, char ** argv, const char *versionString)
|
||||
{
|
||||
bool result = true;
|
||||
bool hasInputPathParam = false;
|
||||
preciseVectorData = false;
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (strcmp("-s", argv[i]) == 0)
|
||||
{
|
||||
preciseVectorData = false;
|
||||
}
|
||||
else if (strcmp("-d", argv[i]) == 0)
|
||||
{
|
||||
if ((i + 1) < argc)
|
||||
{
|
||||
hasInputPathParam = true;
|
||||
strncpy(input_path, argv[i + 1], sizeof(input_path));
|
||||
input_path[sizeof(input_path) - 1] = '\0';
|
||||
|
||||
if (input_path[strlen(input_path) - 1] != '\\' && input_path[strlen(input_path) - 1] != '/')
|
||||
strcat(input_path, "/");
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else if (strcmp("-?", argv[1]) == 0)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else if (strcmp("-l", argv[i]) == 0)
|
||||
{
|
||||
preciseVectorData = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
printf("Extract %s.\n", versionString);
|
||||
printf("%s [-?][-s][-l][-d <path>]\n", argv[0]);
|
||||
printf(" -s : (default) small size (data size optimization), ~500MB less vmap data.\n");
|
||||
printf(" -l : large size, ~500MB more vmap data. (might contain more details)\n");
|
||||
printf(" -d <path>: Path to the vector data source folder.\n");
|
||||
printf(" -? : This message.\n");
|
||||
}
|
||||
|
||||
if (!hasInputPathParam)
|
||||
getGamePath();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
bool success = true;
|
||||
const char *versionString = "V4.03 2015_05";
|
||||
|
||||
// Use command line arguments, when some
|
||||
if (!processArgv(argc, argv, versionString))
|
||||
return 1;
|
||||
|
||||
// some simple check if working dir is dirty
|
||||
else
|
||||
{
|
||||
std::string sdir = std::string(szWorkDirWmo) + "/dir";
|
||||
std::string sdir_bin = std::string(szWorkDirWmo) + "/dir_bin";
|
||||
struct stat status;
|
||||
if (!stat(sdir.c_str(), &status) || !stat(sdir_bin.c_str(), &status))
|
||||
{
|
||||
printf("Your output directory seems to be polluted, please use an empty directory!\n");
|
||||
printf("<press return to exit>");
|
||||
char garbage[2];
|
||||
return scanf("%c", garbage);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Extract %s. Beginning work ....\n\n", versionString);
|
||||
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
// Create the working directory
|
||||
if (mkdir(szWorkDirWmo
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
, 0711
|
||||
#endif
|
||||
))
|
||||
success = (errno == EEXIST);
|
||||
|
||||
// Extract models, listed in GameObjectDisplayInfo.db2
|
||||
ExtractGameobjectModels();
|
||||
|
||||
LoadLiquidTypeDB2Data();
|
||||
|
||||
// extract data
|
||||
if (success)
|
||||
success = ExtractWmo();
|
||||
|
||||
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
//map.dbc
|
||||
if (success)
|
||||
{
|
||||
printf("Read Map.db2 file...\n");
|
||||
DBCFile * dbc = new DBCFile("DBFilesClient\\Map.db2", "nsiifffsssttttttbbbbb");
|
||||
if (!dbc->open())
|
||||
{
|
||||
printf("Fatal error: Invalid Map.db2 file format!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
map_count = dbc->getRecordCount();
|
||||
map_ids = new map_id[map_count];
|
||||
for (unsigned int x = 0; x < map_count; ++x)
|
||||
{
|
||||
map_ids[x].id = dbc->getRecord(x).getUInt(0);
|
||||
|
||||
const char* map_name = dbc->getRecord(x).getString(1);
|
||||
size_t max_map_name_length = sizeof(map_ids[x].name);
|
||||
if (strlen(map_name) >= max_map_name_length)
|
||||
{
|
||||
delete dbc;
|
||||
delete[] map_ids;
|
||||
printf("FATAL ERROR: Map name too long.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
strncpy(map_ids[x].name, map_name, max_map_name_length);
|
||||
map_ids[x].name[max_map_name_length - 1] = '\0';
|
||||
printf("Map - %s\n", map_ids[x].name);
|
||||
}
|
||||
|
||||
delete dbc;
|
||||
ParsMapFiles();
|
||||
delete[] map_ids;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
if (!success)
|
||||
{
|
||||
printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n", versionString, preciseVectorData);
|
||||
getchar();
|
||||
}
|
||||
|
||||
printf("Extract %s. Work complete. No errors.\n", versionString);
|
||||
delete[] LiqType;
|
||||
return 0;
|
||||
}
|
||||
42
src/tools/vmap4_extractor/vmapexport.h
Normal file
42
src/tools/vmap4_extractor/vmapexport.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef VMAPEXPORT_H
|
||||
#define VMAPEXPORT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
enum ModelFlags
|
||||
{
|
||||
MOD_M2 = 1,
|
||||
MOD_WORLDSPAWN = 1<<1,
|
||||
MOD_HAS_BOUND = 1<<2
|
||||
};
|
||||
|
||||
extern const char * szWorkDirWmo;
|
||||
extern const char * szRawVMAPMagic; // vmap magic string for extracted raw vmap data
|
||||
|
||||
bool FileExists(const char * file);
|
||||
void strToLower(char* str);
|
||||
|
||||
bool ExtractSingleWmo(std::string& fname);
|
||||
bool ExtractSingleModel(std::string& fname);
|
||||
|
||||
void ExtractGameobjectModels();
|
||||
|
||||
#endif
|
||||
118
src/tools/vmap4_extractor/wdtfile.cpp
Normal file
118
src/tools/vmap4_extractor/wdtfile.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "wdtfile.h"
|
||||
#include "adtfile.h"
|
||||
#include <cstdio>
|
||||
|
||||
char * wdtGetPlainName(char * FileName)
|
||||
{
|
||||
char * szTemp;
|
||||
|
||||
if((szTemp = strrchr(FileName, '\\')) != NULL)
|
||||
FileName = szTemp + 1;
|
||||
return FileName;
|
||||
}
|
||||
|
||||
WDTFile::WDTFile(char* file_name, char* file_name1):WDT(file_name), gnWMO(0)
|
||||
{
|
||||
filename.append(file_name1,strlen(file_name1));
|
||||
}
|
||||
|
||||
bool WDTFile::init(char* /*map_id*/, unsigned int mapID)
|
||||
{
|
||||
if (WDT.isEof())
|
||||
return false;
|
||||
|
||||
char fourcc[5];
|
||||
uint32 size;
|
||||
|
||||
std::string dirname = std::string(szWorkDirWmo) + "/dir_bin";
|
||||
FILE *dirfile;
|
||||
dirfile = fopen(dirname.c_str(), "ab");
|
||||
if(!dirfile)
|
||||
{
|
||||
// printf("Can't open dirfile!'%s'\n", dirname.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!WDT.isEof())
|
||||
{
|
||||
WDT.read(fourcc,4);
|
||||
WDT.read(&size, 4);
|
||||
|
||||
flipcc(fourcc);
|
||||
fourcc[4] = 0;
|
||||
|
||||
size_t nextpos = WDT.getPos() + size;
|
||||
|
||||
if (!strcmp(fourcc,"MAIN")) { }
|
||||
if (!strcmp(fourcc,"MWMO"))
|
||||
{
|
||||
if (!size)
|
||||
break;
|
||||
|
||||
char *buf = new char[size];
|
||||
WDT.read(buf, size);
|
||||
char *p = buf;
|
||||
while (p < buf + size)
|
||||
{
|
||||
char* s = wdtGetPlainName(p);
|
||||
FixNameCase(s, strlen(s));
|
||||
p = p + strlen(p) + 1;
|
||||
gWmoInstansName.push_back(s);
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
else if (!strcmp(fourcc, "MODF")) // changed on legion
|
||||
{
|
||||
if (!size)
|
||||
break;
|
||||
|
||||
gnWMO = (int)size / 64;
|
||||
for (int i = 0; i < gnWMO; ++i)
|
||||
{
|
||||
int id;
|
||||
WDT.read(&id, 4);
|
||||
WMOInstance inst(WDT, gWmoInstansName[id].c_str(), mapID, 65, 65, dirfile);
|
||||
}
|
||||
}
|
||||
WDT.seek((int)nextpos);
|
||||
}
|
||||
|
||||
WDT.close();
|
||||
fclose(dirfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
WDTFile::~WDTFile(void)
|
||||
{
|
||||
WDT.close();
|
||||
}
|
||||
|
||||
ADTFile* WDTFile::GetMap(int x, int z)
|
||||
{
|
||||
if (!(x >= 0 && z >= 0 && x < 64 && z < 64))
|
||||
return NULL;
|
||||
|
||||
char name[512];
|
||||
|
||||
sprintf(name, "World\\Maps\\%s\\%s_%d_%d_obj0.adt", filename.c_str(), filename.c_str(), x, z);
|
||||
return new ADTFile(name);
|
||||
}
|
||||
46
src/tools/vmap4_extractor/wdtfile.h
Normal file
46
src/tools/vmap4_extractor/wdtfile.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef WDTFILE_H
|
||||
#define WDTFILE_H
|
||||
|
||||
#include "mpqfile.h"
|
||||
#include "wmo.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
class ADTFile;
|
||||
|
||||
class WDTFile
|
||||
{
|
||||
private:
|
||||
MPQFile WDT;
|
||||
std::string filename;
|
||||
public:
|
||||
WDTFile(char* file_name, char* file_name1);
|
||||
~WDTFile(void);
|
||||
bool init(char* map_id, unsigned int mapID);
|
||||
|
||||
std::vector<std::string> gWmoInstansName;
|
||||
int gnWMO;
|
||||
|
||||
ADTFile* GetMap(int x, int z);
|
||||
};
|
||||
|
||||
#endif
|
||||
573
src/tools/vmap4_extractor/wmo.cpp
Normal file
573
src/tools/vmap4_extractor/wmo.cpp
Normal file
@@ -0,0 +1,573 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "wmo.h"
|
||||
#include "vec3d.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#undef min
|
||||
#undef max
|
||||
#include "mpqfile.h"
|
||||
|
||||
using namespace std;
|
||||
extern uint16 *LiqType;
|
||||
|
||||
WMORoot::WMORoot(std::string &filename)
|
||||
: filename(filename), col(0), nTextures(0), nGroups(0), nP(0), nLights(0),
|
||||
nModels(0), nDoodads(0), nDoodadSets(0), RootWMOID(0), liquidType(0)
|
||||
{
|
||||
memset(bbcorn1, 0, sizeof(bbcorn1));
|
||||
memset(bbcorn2, 0, sizeof(bbcorn2));
|
||||
}
|
||||
|
||||
bool WMORoot::open()
|
||||
{
|
||||
MPQFile f(filename.c_str());
|
||||
if(f.isEof ())
|
||||
{
|
||||
printf("No such file.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 size;
|
||||
char fourcc[5];
|
||||
|
||||
while (!f.isEof())
|
||||
{
|
||||
f.read(fourcc,4);
|
||||
f.read(&size, 4);
|
||||
|
||||
flipcc(fourcc);
|
||||
fourcc[4] = 0;
|
||||
|
||||
size_t nextpos = f.getPos() + size;
|
||||
|
||||
if (!strcmp(fourcc,"MOHD")) // header
|
||||
{
|
||||
f.read(&nTextures, 4);
|
||||
f.read(&nGroups, 4);
|
||||
f.read(&nP, 4);
|
||||
f.read(&nLights, 4);
|
||||
f.read(&nModels, 4);
|
||||
f.read(&nDoodads, 4);
|
||||
f.read(&nDoodadSets, 4);
|
||||
f.read(&col, 4);
|
||||
f.read(&RootWMOID, 4);
|
||||
f.read(bbcorn1, 12);
|
||||
f.read(bbcorn2, 12);
|
||||
f.read(&liquidType, 4);
|
||||
f.read(&flagHasSomeOutdoorGroup, 4);
|
||||
f.read(&FlagLod, 4);
|
||||
f.read(&Unk, 4);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
else if (!strcmp(fourcc,"MOTX"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOMT"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOGN"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOGI"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOLT"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MODN"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MODS"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MODD"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOSB"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOPV"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOPT"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOPR"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MFOG"))
|
||||
{
|
||||
}
|
||||
*/
|
||||
f.seek((int)nextpos);
|
||||
}
|
||||
f.close ();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WMORoot::ConvertToVMAPRootWmo(FILE* pOutfile)
|
||||
{
|
||||
//printf("Convert RootWmo...\n");
|
||||
|
||||
fwrite(szRawVMAPMagic, 1, 8, pOutfile);
|
||||
unsigned int nVectors = 0;
|
||||
fwrite(&nVectors,sizeof(nVectors), 1, pOutfile); // will be filled later
|
||||
fwrite(&nGroups, 4, 1, pOutfile);
|
||||
fwrite(&RootWMOID, 4, 1, pOutfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
WMOGroup::WMOGroup(const std::string &filename) :
|
||||
filename(filename), MOPY(0), MOVI(0), MoviEx(0), MOVT(0), MOBA(0), MobaEx(0),
|
||||
hlq(0), LiquEx(0), LiquBytes(0), groupName(0), descGroupName(0), mogpFlags(0),
|
||||
moprIdx(0), moprNItems(0), nBatchA(0), nBatchB(0), nBatchC(0), fogIdx(0),
|
||||
liquidType(0), groupWMOID(0), mopy_size(0), moba_size(0), LiquEx_size(0),
|
||||
nVertices(0), nTriangles(0), liquflags(0)
|
||||
{
|
||||
memset(bbcorn1, 0, sizeof(bbcorn1));
|
||||
memset(bbcorn2, 0, sizeof(bbcorn2));
|
||||
}
|
||||
|
||||
bool WMOGroup::open()
|
||||
{
|
||||
MPQFile f(filename.c_str());
|
||||
if(f.isEof ())
|
||||
{
|
||||
printf("No such file.\n");
|
||||
return false;
|
||||
}
|
||||
uint32 size;
|
||||
char fourcc[5];
|
||||
while (!f.isEof())
|
||||
{
|
||||
f.read(fourcc,4);
|
||||
f.read(&size, 4);
|
||||
flipcc(fourcc);
|
||||
if (!strcmp(fourcc,"MOGP"))//Fix sizeoff = Data size.
|
||||
{
|
||||
size = 68;
|
||||
}
|
||||
fourcc[4] = 0;
|
||||
size_t nextpos = f.getPos() + size;
|
||||
LiquEx_size = 0;
|
||||
liquflags = 0;
|
||||
|
||||
if (!strcmp(fourcc,"MOGP"))//header
|
||||
{
|
||||
f.read(&groupName, 4);
|
||||
f.read(&descGroupName, 4);
|
||||
f.read(&mogpFlags, 4);
|
||||
f.read(bbcorn1, 12);
|
||||
f.read(bbcorn2, 12);
|
||||
f.read(&moprIdx, 2);
|
||||
f.read(&moprNItems, 2);
|
||||
f.read(&nBatchA, 2);
|
||||
f.read(&nBatchB, 2);
|
||||
f.read(&nBatchC, 4);
|
||||
f.read(&fogIdx, 4);
|
||||
f.read(&liquidType, 4);
|
||||
f.read(&groupWMOID,4);
|
||||
f.read(&CanCutTerrain, 4);
|
||||
f.read(&Unused, 4);
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOPY"))
|
||||
{
|
||||
MOPY = new char[size];
|
||||
mopy_size = size;
|
||||
nTriangles = (int)size / 2;
|
||||
f.read(MOPY, size);
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOVI"))
|
||||
{
|
||||
MOVI = new uint16[size/2];
|
||||
f.read(MOVI, size);
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOVT"))
|
||||
{
|
||||
MOVT = new float[size/4];
|
||||
f.read(MOVT, size);
|
||||
nVertices = (int)size / 12;
|
||||
}
|
||||
else if (!strcmp(fourcc,"MONR"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOTV"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(fourcc,"MOBA"))
|
||||
{
|
||||
MOBA = new uint16[size/2];
|
||||
moba_size = size/2;
|
||||
f.read(MOBA, size);
|
||||
}
|
||||
else if (!strcmp(fourcc,"MLIQ"))
|
||||
{
|
||||
liquflags |= 1;
|
||||
hlq = new WMOLiquidHeader();
|
||||
f.read(hlq, 0x1E);
|
||||
LiquEx_size = sizeof(WMOLiquidVert) * hlq->xverts * hlq->yverts;
|
||||
LiquEx = new WMOLiquidVert[hlq->xverts * hlq->yverts];
|
||||
f.read(LiquEx, LiquEx_size);
|
||||
int nLiquBytes = hlq->xtiles * hlq->ytiles;
|
||||
LiquBytes = new char[nLiquBytes];
|
||||
f.read(LiquBytes, nLiquBytes);
|
||||
|
||||
/* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
|
||||
llog << filename;
|
||||
llog << "\nbbox: " << bbcorn1[0] << ", " << bbcorn1[1] << ", " << bbcorn1[2] << " | " << bbcorn2[0] << ", " << bbcorn2[1] << ", " << bbcorn2[2];
|
||||
llog << "\nlpos: " << hlq->pos_x << ", " << hlq->pos_y << ", " << hlq->pos_z;
|
||||
llog << "\nx-/yvert: " << hlq->xverts << "/" << hlq->yverts << " size: " << size << " expected size: " << 30 + hlq->xverts*hlq->yverts*8 + hlq->xtiles*hlq->ytiles << std::endl;
|
||||
llog.close(); */
|
||||
}
|
||||
f.seek((int)nextpos);
|
||||
}
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool preciseVectorData)
|
||||
{
|
||||
fwrite(&mogpFlags,sizeof(uint32),1,output);
|
||||
fwrite(&groupWMOID,sizeof(uint32),1,output);
|
||||
// group bound
|
||||
fwrite(bbcorn1, sizeof(float), 3, output);
|
||||
fwrite(bbcorn2, sizeof(float), 3, output);
|
||||
fwrite(&liquflags,sizeof(uint32),1,output);
|
||||
int nColTriangles = 0;
|
||||
if (preciseVectorData)
|
||||
{
|
||||
char GRP[] = "GRP ";
|
||||
fwrite(GRP,1,4,output);
|
||||
|
||||
int k = 0;
|
||||
int moba_batch = moba_size/12;
|
||||
MobaEx = new int[moba_batch*4];
|
||||
for(int i=8; i<moba_size; i+=12)
|
||||
{
|
||||
MobaEx[k++] = MOBA[i];
|
||||
}
|
||||
int moba_size_grp = moba_batch*4+4;
|
||||
fwrite(&moba_size_grp,4,1,output);
|
||||
fwrite(&moba_batch,4,1,output);
|
||||
fwrite(MobaEx,4,k,output);
|
||||
delete [] MobaEx;
|
||||
|
||||
uint32 nIdexes = nTriangles * 3;
|
||||
|
||||
if(fwrite("INDX",4, 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file nbraches ID");
|
||||
exit(0);
|
||||
}
|
||||
int wsize = sizeof(uint32) + sizeof(unsigned short) * nIdexes;
|
||||
if(fwrite(&wsize, sizeof(int), 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file wsize");
|
||||
// no need to exit?
|
||||
}
|
||||
if(fwrite(&nIdexes, sizeof(uint32), 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file nIndexes");
|
||||
exit(0);
|
||||
}
|
||||
if(nIdexes >0)
|
||||
{
|
||||
if(fwrite(MOVI, sizeof(unsigned short), nIdexes, output) != nIdexes)
|
||||
{
|
||||
printf("Error while writing file indexarray");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if(fwrite("VERT",4, 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file nbraches ID");
|
||||
exit(0);
|
||||
}
|
||||
wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
|
||||
if(fwrite(&wsize, sizeof(int), 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file wsize");
|
||||
// no need to exit?
|
||||
}
|
||||
if(fwrite(&nVertices, sizeof(int), 1, output) != 1)
|
||||
{
|
||||
printf("Error while writing file nVertices");
|
||||
exit(0);
|
||||
}
|
||||
if(nVertices >0)
|
||||
{
|
||||
if(fwrite(MOVT, sizeof(float)*3, nVertices, output) != nVertices)
|
||||
{
|
||||
printf("Error while writing file vectors");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
nColTriangles = nTriangles;
|
||||
}
|
||||
else
|
||||
{
|
||||
char GRP[] = "GRP ";
|
||||
fwrite(GRP,1,4,output);
|
||||
int k = 0;
|
||||
int moba_batch = moba_size/12;
|
||||
MobaEx = new int[moba_batch*4];
|
||||
for(int i=8; i<moba_size; i+=12)
|
||||
{
|
||||
MobaEx[k++] = MOBA[i];
|
||||
}
|
||||
|
||||
int moba_size_grp = moba_batch*4+4;
|
||||
fwrite(&moba_size_grp,4,1,output);
|
||||
fwrite(&moba_batch,4,1,output);
|
||||
fwrite(MobaEx,4,k,output);
|
||||
delete [] MobaEx;
|
||||
|
||||
//-------INDX------------------------------------
|
||||
//-------MOPY--------
|
||||
MoviEx = new uint16[nTriangles*3]; // "worst case" size...
|
||||
int *IndexRenum = new int[nVertices];
|
||||
memset(IndexRenum, 0xFF, nVertices*sizeof(int));
|
||||
for (int i=0; i<nTriangles; ++i)
|
||||
{
|
||||
// Skip no collision triangles
|
||||
if (MOPY[2*i]&WMO_MATERIAL_NO_COLLISION ||
|
||||
!(MOPY[2*i]&(WMO_MATERIAL_HINT|WMO_MATERIAL_COLLIDE_HIT)) )
|
||||
continue;
|
||||
// Use this triangle
|
||||
for (int j=0; j<3; ++j)
|
||||
{
|
||||
IndexRenum[MOVI[3*i + j]] = 1;
|
||||
MoviEx[3*nColTriangles + j] = MOVI[3*i + j];
|
||||
}
|
||||
++nColTriangles;
|
||||
}
|
||||
|
||||
// assign new vertex index numbers
|
||||
int nColVertices = 0;
|
||||
for (uint32 i=0; i<nVertices; ++i)
|
||||
{
|
||||
if (IndexRenum[i] == 1)
|
||||
{
|
||||
IndexRenum[i] = nColVertices;
|
||||
++nColVertices;
|
||||
}
|
||||
}
|
||||
|
||||
// translate triangle indices to new numbers
|
||||
for (int i=0; i<3*nColTriangles; ++i)
|
||||
{
|
||||
assert(MoviEx[i] < nVertices);
|
||||
MoviEx[i] = IndexRenum[MoviEx[i]];
|
||||
}
|
||||
|
||||
// write triangle indices
|
||||
int INDX[] = {0x58444E49, nColTriangles*6+4, nColTriangles*3};
|
||||
fwrite(INDX,4,3,output);
|
||||
fwrite(MoviEx,2,nColTriangles*3,output);
|
||||
|
||||
// write vertices
|
||||
int VERT[] = {0x54524556, nColVertices*3*static_cast<int>(sizeof(float))+4, nColVertices};// "VERT"
|
||||
int check = 3*nColVertices;
|
||||
fwrite(VERT,4,3,output);
|
||||
for (uint32 i=0; i<nVertices; ++i)
|
||||
if(IndexRenum[i] >= 0)
|
||||
check -= fwrite(MOVT+3*i, sizeof(float), 3, output);
|
||||
|
||||
assert(check==0);
|
||||
|
||||
delete [] MoviEx;
|
||||
delete [] IndexRenum;
|
||||
}
|
||||
|
||||
//------LIQU------------------------
|
||||
if (LiquEx_size != 0)
|
||||
{
|
||||
int LIQU_h[] = {0x5551494C, static_cast<int>(sizeof(WMOLiquidHeader) + LiquEx_size) + hlq->xtiles*hlq->ytiles};// "LIQU"
|
||||
fwrite(LIQU_h, 4, 2, output);
|
||||
|
||||
// according to WoW.Dev Wiki:
|
||||
uint32 liquidEntry;
|
||||
if (rootWMO->liquidType & 4)
|
||||
liquidEntry = liquidType;
|
||||
else if (liquidType == 15)
|
||||
liquidEntry = 0;
|
||||
else
|
||||
liquidEntry = liquidType + 1;
|
||||
|
||||
if (!liquidEntry)
|
||||
{
|
||||
int v1; // edx@1
|
||||
int v2; // eax@1
|
||||
|
||||
v1 = hlq->xtiles * hlq->ytiles;
|
||||
v2 = 0;
|
||||
if (v1 > 0)
|
||||
{
|
||||
while ((LiquBytes[v2] & 0xF) == 15)
|
||||
{
|
||||
++v2;
|
||||
if (v2 >= v1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (v2 < v1 && (LiquBytes[v2] & 0xF) != 15)
|
||||
liquidEntry = (LiquBytes[v2] & 0xF) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (liquidEntry && liquidEntry < 21)
|
||||
{
|
||||
switch ((liquidEntry - 1) & 3)
|
||||
{
|
||||
case 0:
|
||||
liquidEntry = ((mogpFlags & 0x80000) != 0) + 13;
|
||||
break;
|
||||
case 1:
|
||||
liquidEntry = 14;
|
||||
break;
|
||||
case 2:
|
||||
liquidEntry = 19;
|
||||
break;
|
||||
case 3:
|
||||
liquidEntry = 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hlq->type = liquidEntry;
|
||||
|
||||
/* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
|
||||
llog << filename;
|
||||
llog << ":\nliquidEntry: " << liquidEntry << " type: " << hlq->type << " (root:" << rootWMO->liquidType << " group:" << liquidType << ")\n";
|
||||
llog.close(); */
|
||||
|
||||
fwrite(hlq, sizeof(WMOLiquidHeader), 1, output);
|
||||
// only need height values, the other values are unknown anyway
|
||||
for (uint32 i = 0; i<LiquEx_size/sizeof(WMOLiquidVert); ++i)
|
||||
fwrite(&LiquEx[i].height, sizeof(float), 1, output);
|
||||
// todo: compress to bit field
|
||||
fwrite(LiquBytes, 1, hlq->xtiles*hlq->ytiles, output);
|
||||
}
|
||||
|
||||
return nColTriangles;
|
||||
}
|
||||
|
||||
WMOGroup::~WMOGroup()
|
||||
{
|
||||
delete [] MOPY;
|
||||
delete [] MOVI;
|
||||
delete [] MOVT;
|
||||
delete [] MOBA;
|
||||
delete hlq;
|
||||
delete [] LiquEx;
|
||||
delete [] LiquBytes;
|
||||
}
|
||||
|
||||
WMOInstance::WMOInstance(MPQFile& f, char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile)
|
||||
: currx(0), curry(0), wmo(NULL), doodadset(0), pos(), indx(0), id(0), d2(0), d3(0)
|
||||
{
|
||||
float ff[3];
|
||||
f.read(&id, 4);
|
||||
f.read(ff,12);
|
||||
pos = Vec3D(ff[0],ff[1],ff[2]);
|
||||
f.read(ff,12);
|
||||
rot = Vec3D(ff[0],ff[1],ff[2]);
|
||||
f.read(ff,12);
|
||||
pos2 = Vec3D(ff[0],ff[1],ff[2]);
|
||||
f.read(ff,12);
|
||||
pos3 = Vec3D(ff[0],ff[1],ff[2]);
|
||||
f.read(&d2,4); //flags + doodadSet
|
||||
|
||||
uint16 trash,adtId;
|
||||
f.read(&adtId, 2); //nameSet
|
||||
f.read(&trash, 2); //unk
|
||||
|
||||
//-----------add_in _dir_file----------------
|
||||
|
||||
char tempname[512];
|
||||
sprintf(tempname, "%s/%s", szWorkDirWmo, WmoInstName);
|
||||
FILE *input;
|
||||
input = fopen(tempname, "r+b");
|
||||
|
||||
if(!input)
|
||||
{
|
||||
// printf("WMOInstance::WMOInstance: couldn't open %s\n", tempname);
|
||||
//system("pause");
|
||||
return;
|
||||
}
|
||||
|
||||
// printf("WMOInstance::open %s\n", tempname);
|
||||
|
||||
fseek(input, 8, SEEK_SET); // get the correct no of vertices
|
||||
int nVertices;
|
||||
int count = fread(&nVertices, sizeof (int), 1, input);
|
||||
fclose(input);
|
||||
|
||||
if (count != 1 || nVertices == 0)
|
||||
return;
|
||||
|
||||
float x,z;
|
||||
x = pos.x;
|
||||
z = pos.z;
|
||||
if(x==0 && z == 0)
|
||||
{
|
||||
pos.x = 533.33333f*32;
|
||||
pos.z = 533.33333f*32;
|
||||
}
|
||||
pos = fixCoords(pos);
|
||||
pos2 = fixCoords(pos2);
|
||||
pos3 = fixCoords(pos3);
|
||||
|
||||
float scale = 1.0f;
|
||||
uint32 flags = MOD_HAS_BOUND;
|
||||
if (tileX == 65 && tileY == 65)
|
||||
flags |= MOD_WORLDSPAWN;
|
||||
|
||||
fwrite(&mapID, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&tileX, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&tileY, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&flags, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&adtId, sizeof(uint16), 1, pDirfile);
|
||||
fwrite(&id, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(&pos, sizeof(float), 3, pDirfile);
|
||||
fwrite(&rot, sizeof(float), 3, pDirfile);
|
||||
fwrite(&scale, sizeof(float), 1, pDirfile);
|
||||
fwrite(&pos2, sizeof(float), 3, pDirfile);
|
||||
fwrite(&pos3, sizeof(float), 3, pDirfile);
|
||||
uint32 nlen = strlen(WmoInstName);
|
||||
fwrite(&nlen, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(WmoInstName, sizeof(char), nlen, pDirfile);
|
||||
|
||||
/*fprintf(pDirfile,"MapName %s WmoInstName %s pos.x %f, pos.y %f, pos.z%f, rot.x %f, rot.y %f, rot.z %f nVertices %d\n",
|
||||
MapName,
|
||||
WmoInstName,
|
||||
(float) x, (float) pos.y, (float) z,
|
||||
(float) rot.x, (float) rot.y, (float) rot.z,
|
||||
nVertices); */
|
||||
|
||||
// fclose(dirfile);
|
||||
}
|
||||
138
src/tools/vmap4_extractor/wmo.h
Normal file
138
src/tools/vmap4_extractor/wmo.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef WMO_H
|
||||
#define WMO_H
|
||||
#define TILESIZE (533.33333f)
|
||||
#define CHUNKSIZE ((TILESIZE) / 16.0f)
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "vec3d.h"
|
||||
#include "mpqfile.h"
|
||||
|
||||
// MOPY flags
|
||||
#define WMO_MATERIAL_NOCAMCOLLIDE 0x01
|
||||
#define WMO_MATERIAL_DETAIL 0x02
|
||||
#define WMO_MATERIAL_NO_COLLISION 0x04
|
||||
#define WMO_MATERIAL_HINT 0x08
|
||||
#define WMO_MATERIAL_RENDER 0x10
|
||||
#define WMO_MATERIAL_COLLIDE_HIT 0x20
|
||||
#define WMO_MATERIAL_WALL_SURFACE 0x40
|
||||
|
||||
class WMOInstance;
|
||||
class WMOManager;
|
||||
class MPQFile;
|
||||
|
||||
/* for whatever reason a certain company just can't stick to one coordinate system... */
|
||||
static inline Vec3D fixCoords(const Vec3D &v){ return Vec3D(v.z, v.x, v.y); }
|
||||
|
||||
class WMORoot
|
||||
{
|
||||
private:
|
||||
std::string filename;
|
||||
public:
|
||||
unsigned int col;
|
||||
uint32 nTextures, nGroups, nP, nLights, nModels, nDoodads, nDoodadSets, RootWMOID, liquidType, flagHasSomeOutdoorGroup, FlagLod, Unk;
|
||||
float bbcorn1[3];
|
||||
float bbcorn2[3];
|
||||
|
||||
WMORoot(std::string& filename);
|
||||
|
||||
bool open();
|
||||
bool ConvertToVMAPRootWmo(FILE* output);
|
||||
};
|
||||
|
||||
struct WMOLiquidHeader
|
||||
{
|
||||
int xverts, yverts, xtiles, ytiles;
|
||||
float pos_x;
|
||||
float pos_y;
|
||||
float pos_z;
|
||||
short type;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct WMOLiquidVert
|
||||
{
|
||||
uint16 unk1;
|
||||
uint16 unk2;
|
||||
float height;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
class WMOGroup
|
||||
{
|
||||
private:
|
||||
std::string filename;
|
||||
public:
|
||||
// MOGP
|
||||
|
||||
char* MOPY;
|
||||
uint16* MOVI;
|
||||
uint16* MoviEx;
|
||||
float* MOVT;
|
||||
uint16* MOBA;
|
||||
int* MobaEx;
|
||||
WMOLiquidHeader* hlq;
|
||||
WMOLiquidVert* LiquEx;
|
||||
char* LiquBytes;
|
||||
int groupName, descGroupName;
|
||||
int mogpFlags;
|
||||
float bbcorn1[3];
|
||||
float bbcorn2[3];
|
||||
uint16 moprIdx;
|
||||
uint16 moprNItems;
|
||||
uint16 nBatchA;
|
||||
uint16 nBatchB;
|
||||
uint32 nBatchC, fogIdx, liquidType, groupWMOID, CanCutTerrain, Unused;
|
||||
|
||||
int mopy_size, moba_size;
|
||||
int LiquEx_size;
|
||||
unsigned int nVertices; // number when loaded
|
||||
int nTriangles; // number when loaded
|
||||
uint32 liquflags;
|
||||
|
||||
WMOGroup(std::string const& filename);
|
||||
~WMOGroup();
|
||||
|
||||
bool open();
|
||||
int ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool preciseVectorData);
|
||||
};
|
||||
|
||||
class WMOInstance
|
||||
{
|
||||
static std::set<int> ids;
|
||||
public:
|
||||
std::string MapName;
|
||||
int currx;
|
||||
int curry;
|
||||
WMOGroup* wmo;
|
||||
int doodadset;
|
||||
Vec3D pos;
|
||||
Vec3D pos2, pos3, rot;
|
||||
uint32 indx, id, d2, d3;
|
||||
|
||||
WMOInstance(MPQFile&f , char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile);
|
||||
|
||||
static void reset();
|
||||
};
|
||||
|
||||
#endif
|
||||
135
src/tools/web_api/CMakeLists.txt
Normal file
135
src/tools/web_api/CMakeLists.txt
Normal file
@@ -0,0 +1,135 @@
|
||||
include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(http
|
||||
GIT_REPOSITORY https://github.com/yhirose/cpp-httplib
|
||||
CONFIGURE_COMMAND ""
|
||||
UPDATE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
|
||||
ExternalProject_Add(cereal
|
||||
GIT_REPOSITORY https://github.com/USCiLab/cereal
|
||||
CONFIGURE_COMMAND ""
|
||||
UPDATE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
|
||||
add_library(captcha STATIC dep/libcaptcha.c)
|
||||
|
||||
SET (SRCS
|
||||
src/main.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/server/game/Accounts/AccountMgr.cpp
|
||||
dep/tweetnacl/tweetnacl.c
|
||||
dep/smtp-client/src/smtp.c
|
||||
dep/smtp-client/src/SMTPMail.cpp
|
||||
)
|
||||
|
||||
# we use the filesystem API of C++17
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
add_executable(webapi ${SRCS})
|
||||
add_dependencies(webapi http captcha cereal)
|
||||
|
||||
if( UNIX AND NOT NOJEM AND NOT APPLE AND NOT WIN32 )
|
||||
set_target_properties(webapi PROPERTIES LINK_FLAGS "-pthread")
|
||||
endif()
|
||||
|
||||
target_compile_definitions(webapi PUBLIC _WEB_API)
|
||||
|
||||
ExternalProject_Get_Property(http SOURCE_DIR)
|
||||
set(HTTP_SOURCE_DIR ${SOURCE_DIR})
|
||||
|
||||
ExternalProject_Get_Property(cereal SOURCE_DIR)
|
||||
set(CEREAL_SOURCE_DIR ${SOURCE_DIR})
|
||||
|
||||
target_include_directories(webapi PUBLIC
|
||||
${HTTP_SOURCE_DIR}
|
||||
${CEREAL_SOURCE_DIR}/include
|
||||
dep/tweetnacl
|
||||
dep/smtp-client/src
|
||||
${CMAKE_SOURCE_DIR}/src/common
|
||||
${CMAKE_SOURCE_DIR}/src/common/Logging
|
||||
${CMAKE_SOURCE_DIR}/src/common/Utilities
|
||||
${CMAKE_SOURCE_DIR}/src/common/Threading
|
||||
${CMAKE_SOURCE_DIR}/src/common/Debugging
|
||||
${CMAKE_SOURCE_DIR}/src/common/Database
|
||||
${CMAKE_SOURCE_DIR}/src/common/Cryptography
|
||||
${CMAKE_SOURCE_DIR}/src/server/game/Accounts
|
||||
|
||||
${ACE_INCLUDE_DIR}
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
)
|
||||
target_link_libraries(webapi PUBLIC
|
||||
shared
|
||||
captcha
|
||||
${ACE_LIBRARY}
|
||||
${MYSQL_LIBRARY}
|
||||
${OPENSSL_LIBRARIES}
|
||||
)
|
||||
|
||||
set_target_properties(webapi PROPERTIES FOLDER "tools")
|
||||
|
||||
if( WIN32 )
|
||||
if ( MSVC )
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/webapi.conf.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
|
||||
)
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/confirmation.mail.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
|
||||
)
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/registration.mail.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
|
||||
)
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/reset.mail.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
|
||||
)
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/validation.mail.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/
|
||||
)
|
||||
elseif ( MINGW )
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/webapi.conf.dist ${CMAKE_BINARY_DIR}/bin/
|
||||
)
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/confirmation.mail.dist ${CMAKE_BINARY_DIR}/bin/
|
||||
)
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/registration.mail.dist ${CMAKE_BINARY_DIR}/bin/
|
||||
)
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/reset.mail.dist ${CMAKE_BINARY_DIR}/bin/
|
||||
)
|
||||
add_custom_command(TARGET webapi
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/validation.mail.dist ${CMAKE_BINARY_DIR}/bin/
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if( UNIX )
|
||||
install(TARGETS webapi DESTINATION bin)
|
||||
install(FILES webapi.conf.dist DESTINATION ${CONF_DIR})
|
||||
install(FILES confirmation.mail.dist DESTINATION ${CONF_DIR})
|
||||
install(FILES registration.mail.dist DESTINATION ${CONF_DIR})
|
||||
install(FILES reset.mail.dist DESTINATION ${CONF_DIR})
|
||||
install(FILES validation.mail.dist DESTINATION ${CONF_DIR})
|
||||
elseif( WIN32 )
|
||||
install(TARGETS webapi DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
install(FILES webapi.conf.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
install(FILES confirmation.mail.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
install(FILES registration.mail.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
install(FILES reset.mail.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
install(FILES validation.mail.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
0
src/tools/web_api/README.md
Normal file
0
src/tools/web_api/README.md
Normal file
18
src/tools/web_api/confirmation.mail.dist
Normal file
18
src/tools/web_api/confirmation.mail.dist
Normal file
@@ -0,0 +1,18 @@
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd
|
||||
Content-Type: text/plain
|
||||
|
||||
Please open the following link in your webbrowser to complete the upgrade for your WoW account (you will be able to login to WoW then using this email address):
|
||||
<insert-url>
|
||||
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd
|
||||
Content-Type: text/html
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>WoW Account Upgrade Confirmation</title>
|
||||
</head>
|
||||
<body>Please click the following link to complete the upgrade for your WoW account (you will be able to login to WoW then using this email address):<br>
|
||||
<a href="<insert-url>"><insert-url></a>
|
||||
</body></html>
|
||||
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd--
|
||||
257
src/tools/web_api/dep/libcaptcha.c
Normal file
257
src/tools/web_api/dep/libcaptcha.c
Normal file
@@ -0,0 +1,257 @@
|
||||
// Version 2012-02-20 (http://github.com/ITikhonov/captcha/tree/bbbaaa33ad3f94ce3f091badba51b44a231f12fd)
|
||||
// zlib/libpng license is at the end of this file
|
||||
|
||||
const int gifsize;
|
||||
void captcha(unsigned char im[70*200], unsigned char l[6]);
|
||||
void makegif(unsigned char im[70*200], unsigned char gif[17646]);
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
static int8_t lt0[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-4,11,7,5,3,1,0,0,0,1,3,7,13,-100,-2,11,3,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-1,7,0,0,0,0,0,0,3,9,11,9,3,0,0,0,0,13,-100,9,0,0,0,0,0,0,3,-5,3,0,0,0,7,-100,5,0,0,0,0,0,1,13,-5,9,0,0,0,1,-100,7,0,0,0,0,1,13,-6,13,0,0,0,0,-100,-1,9,1,0,5,13,-8,0,0,0,0,13,-100,-14,0,0,0,0,11,-100,-14,0,0,0,0,11,-100,-14,0,0,0,0,11,-100,-12,13,5,0,0,0,0,11,-100,-8,13,9,5,1,0,0,0,0,0,0,11,-100,-4,13,7,3,1,0,0,0,0,1,1,0,0,0,0,11,-100,-2,13,5,0,0,0,0,0,5,9,13,-2,0,0,0,0,11,-100,-1,13,1,0,0,0,0,7,-6,0,0,0,0,11,-100,13,1,0,0,0,0,13,-7,0,0,0,0,11,-100,5,0,0,0,0,5,-8,0,0,0,0,11,-100,0,0,0,0,0,11,-8,0,0,0,0,11,-100,0,0,0,0,0,13,-7,13,0,0,0,0,11,-100,1,0,0,0,0,-7,9,0,0,0,0,0,9,-3,9,-100,5,0,0,0,0,3,13,-3,11,3,0,0,0,0,0,0,0,9,13,3,5,-100,13,0,0,0,0,0,0,1,1,0,0,0,1,11,9,0,0,0,0,0,0,1,13,-100,-1,11,1,0,0,0,0,0,0,0,0,5,-3,9,0,0,0,0,0,11,-100,-2,13,7,3,0,0,0,3,7,13,-5,9,0,1,3,9,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt1[] = { -100,-100,-4,13,5,0,3,-100,-3,11,1,0,0,0,7,-100,-2,7,0,0,0,0,0,3,-100,13,3,0,0,0,0,0,0,5,-100,1,0,0,0,0,0,0,0,9,-100,1,0,0,0,0,0,0,0,13,-100,13,3,0,0,0,0,0,1,-100,-2,5,0,0,0,0,5,-100,-3,0,0,0,0,9,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,9,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,3,13,9,5,3,1,0,0,1,3,5,9,-100,-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,13,-100,-3,0,0,0,0,0,5,13,-2,13,11,9,5,0,0,0,0,1,13,-100,-3,0,0,0,0,1,-8,13,1,0,0,0,5,-100,-3,3,0,0,0,5,-9,13,0,0,0,0,11,-100,-3,0,0,0,0,9,-10,7,0,0,0,5,-100,-3,1,0,0,0,11,-10,13,0,0,0,0,-100,-3,3,0,0,0,11,-11,3,0,0,0,11,-100,-3,1,0,0,0,11,-11,7,0,0,0,7,-100,-3,0,0,0,0,11,-11,9,0,0,0,3,-100,-3,0,0,0,0,11,-11,11,0,0,0,1,-100,-3,0,0,0,0,11,-11,11,0,0,0,1,-100,-3,0,0,0,0,11,-11,11,0,0,0,0,-100,-3,0,0,0,0,11,-11,9,0,0,0,0,-100,-3,0,0,0,0,11,-11,7,0,0,0,3,-100,-3,0,0,0,0,11,-11,3,0,0,0,7,-100,-3,0,0,0,0,11,-11,0,0,0,0,11,-100,-3,0,0,0,0,11,-10,9,0,0,0,3,-100,-3,0,0,0,0,9,-10,3,0,0,0,11,-100,-3,0,0,0,0,3,-9,11,0,0,0,5,-100,-2,13,0,0,0,0,0,9,-7,11,1,0,0,3,-100,-2,7,0,0,0,0,0,0,7,13,-2,13,9,3,0,0,0,3,13,-100,-2,13,0,0,5,13,11,1,0,0,0,0,0,0,0,0,0,7,-100,-3,9,11,-4,7,3,1,0,0,1,5,9,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt2[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,13,7,3,1,0,0,1,3,7,13,-100,-5,9,0,0,0,0,0,0,0,0,0,0,5,13,-100,-3,13,3,0,0,0,5,13,13,7,0,0,0,0,0,1,13,-100,-2,13,1,0,0,0,9,-4,7,0,0,0,0,0,1,-100,-1,13,1,0,0,0,9,-6,5,0,0,0,0,0,13,-100,-1,5,0,0,0,3,-8,1,0,0,0,3,-100,13,0,0,0,0,11,-8,13,3,0,3,-100,7,0,0,0,1,-100,5,0,0,0,5,-100,3,0,0,0,9,-100,1,0,0,0,11,-100,0,0,0,0,11,-100,0,0,0,0,11,-100,0,0,0,0,11,-100,0,0,0,0,9,-100,1,0,0,0,5,-100,5,0,0,0,0,13,-100,11,0,0,0,0,7,-100,-1,3,0,0,0,0,13,-100,-1,11,0,0,0,0,3,-12,9,-100,-2,7,0,0,0,0,3,13,-8,9,1,3,-100,-3,5,0,0,0,0,1,9,-5,9,3,0,0,11,-100,-4,5,0,0,0,0,0,0,1,1,1,0,0,0,0,11,-100,-5,9,1,0,0,0,0,0,0,0,0,0,3,13,-100,-7,11,7,3,1,0,1,3,7,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt3[] = { -100,-100,-100,-100,-18,11,3,0,-100,-16,13,3,0,0,0,-100,-14,9,3,0,0,0,0,0,-100,-13,3,0,0,0,0,0,0,0,-100,-13,0,0,0,0,0,0,0,0,-100,-13,9,1,0,0,0,0,0,0,-100,-15,13,5,0,0,0,0,-100,-17,1,0,0,0,-100,-17,3,0,0,0,-100,-17,1,0,0,0,-100,-17,0,0,0,0,-100,-16,13,0,0,0,0,-100,-16,13,0,0,0,0,-100,-6,11,5,3,1,0,0,1,5,9,13,13,0,0,0,0,-100,-4,13,3,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,-100,-3,13,1,0,0,0,0,5,11,-1,13,11,3,0,0,0,0,0,0,-100,-2,13,1,0,0,0,0,7,-6,11,0,0,0,0,0,-100,-2,3,0,0,0,0,9,-8,11,0,0,0,0,-100,-1,9,0,0,0,0,7,-9,11,0,0,0,0,-100,-1,1,0,0,0,0,13,-9,11,0,0,0,0,-100,11,0,0,0,0,3,-10,11,0,0,0,0,-100,5,0,0,0,0,13,-10,11,0,0,0,0,-100,3,0,0,0,3,-11,11,0,0,0,0,-100,0,0,0,0,7,-11,11,0,0,0,0,-100,0,0,0,0,11,-11,11,0,0,0,0,-100,0,0,0,0,11,-11,11,0,0,0,0,-100,0,0,0,0,11,-11,11,0,0,0,0,-100,1,0,0,0,9,-11,11,0,0,0,0,-100,3,0,0,0,7,-11,11,0,0,0,0,-100,7,0,0,0,3,-11,11,0,0,0,0,-100,13,0,0,0,0,13,-10,13,0,0,0,0,-100,-1,3,0,0,0,5,-11,0,0,0,0,-100,-1,13,0,0,0,0,11,-10,0,0,0,0,-100,-2,7,0,0,0,1,13,-8,13,0,0,0,0,13,-100,-3,5,0,0,0,1,11,-7,5,0,0,0,0,9,-100,-4,5,0,0,0,0,3,9,13,-1,13,11,1,0,0,0,0,0,0,0,5,-100,-5,9,1,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,1,13,-100,-7,9,3,1,0,0,3,7,13,-1,11,1,0,1,5,7,11,-100,-18,13,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt4[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-7,13,5,1,1,0,1,3,9,13,-100,-6,5,0,0,0,0,0,0,0,0,0,9,-100,-4,11,1,0,0,3,11,-1,13,7,1,0,0,0,9,-100,-3,9,0,0,0,1,13,-5,3,0,0,1,-100,-2,9,0,0,0,0,13,-6,11,0,0,0,9,-100,-1,13,0,0,0,0,9,-8,0,0,0,1,-100,-1,5,0,0,0,0,13,-8,3,0,0,0,11,-100,-1,0,0,0,0,0,-8,13,1,0,0,0,5,-100,9,0,0,0,0,0,3,11,-4,13,11,1,0,0,0,0,1,-100,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,-100,1,0,0,0,1,13,-100,0,0,0,0,11,-100,0,0,0,0,11,-100,1,0,0,0,9,-100,3,0,0,0,7,-100,7,0,0,0,5,-100,13,0,0,0,0,11,-100,-1,5,0,0,0,1,13,-100,-1,13,1,0,0,0,1,13,-10,13,11,-100,-2,11,0,0,0,0,1,13,-8,13,1,1,-100,-3,11,0,0,0,0,0,7,13,-4,11,7,0,0,9,-100,-4,11,1,0,0,0,0,0,1,1,1,0,0,0,0,7,-100,-5,13,5,0,0,0,0,0,0,0,0,0,1,9,-100,-7,13,7,3,0,0,0,1,5,9,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt5[] = { -100,-100,-100,-100,-9,13,9,3,1,0,1,5,13,-100,-8,7,0,0,0,0,0,0,0,3,-100,-7,3,0,0,0,0,0,0,0,0,1,-100,-6,5,0,0,0,0,0,0,0,0,0,3,-100,-5,13,0,0,3,13,9,1,0,0,0,0,11,-100,-5,9,0,0,13,-2,13,5,0,1,9,-100,-5,5,0,0,-100,-5,1,0,1,-100,-5,1,0,0,-100,-5,0,0,0,-100,-5,0,0,0,13,-100,-5,0,0,0,9,-100,-5,0,0,0,7,-100,-5,0,0,0,5,-100,-3,13,7,0,0,0,0,9,-1,13,11,13,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-1,11,13,-1,7,0,0,0,0,5,-1,13,11,13,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,11,-100,-5,0,0,0,0,7,-100,-3,13,5,0,0,0,0,0,7,13,-100,-1,5,0,0,0,0,0,0,0,0,0,0,0,1,11,-100,-1,7,1,0,0,0,0,0,0,0,0,1,3,7,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt6[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-7,11,7,3,1,0,0,1,3,7,13,-4,13,7,5,7,11,-100,-5,11,3,0,0,0,0,0,0,0,0,0,0,5,13,13,5,0,0,0,0,0,-100,-4,9,0,0,0,5,13,-1,13,9,3,0,0,0,0,0,0,0,0,0,0,0,1,-100,-3,11,0,0,0,5,-6,5,0,0,0,0,0,11,13,9,3,0,9,-100,-2,13,0,0,0,0,13,-7,1,0,0,0,0,13,-100,-2,1,0,0,0,7,-8,7,0,0,0,0,7,-100,-2,0,0,0,0,9,-8,11,0,0,0,0,3,-100,-2,0,0,0,0,11,-9,0,0,0,0,1,-100,-2,0,0,0,0,11,-9,0,0,0,0,0,-100,-2,0,0,0,0,9,-8,13,0,0,0,0,1,-100,-2,3,0,0,0,5,-8,9,0,0,0,0,7,-100,-2,13,1,0,0,0,13,-7,5,0,0,0,0,13,-100,-3,11,0,0,0,3,13,-5,7,0,0,0,0,11,-100,-4,7,0,0,0,1,9,13,-1,13,7,0,0,0,1,11,-100,-4,13,0,0,0,0,0,0,0,0,0,0,0,5,13,-100,-4,13,0,0,0,0,0,0,1,3,5,9,-100,-2,13,5,0,11,-100,-1,13,1,0,0,-100,-1,3,0,0,0,1,7,13,-100,-1,0,0,0,0,0,0,0,1,3,7,9,11,13,-100,-1,5,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,11,-100,-2,11,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,11,-100,-4,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-3,9,1,0,3,9,13,13,11,7,3,0,0,0,0,0,0,0,0,0,13,-100,-1,7,1,0,0,9,-8,11,7,3,0,0,0,0,0,5,-100,9,0,0,0,3,-13,11,1,0,0,1,-100,1,0,0,0,9,-15,0,0,0,-100,0,0,0,0,9,-14,13,0,0,1,-100,3,0,0,0,1,-14,7,0,0,5,-100,11,0,0,0,0,5,-12,11,0,0,0,13,-100,-1,11,1,0,0,0,1,7,11,13,-1,13,13,11,9,5,3,1,0,0,3,13,-100,-3,9,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,9,-100,-6,9,7,3,1,1,0,0,1,1,3,7,11,-100,-101 };
|
||||
static int8_t lt7[] = { -100,-100,-100,-100,-4,13,7,1,9,-100,-2,13,7,0,0,0,3,-100,-1,7,0,0,0,0,0,5,-100,1,0,0,0,0,0,0,7,-100,3,0,0,0,0,0,0,7,-100,13,7,0,0,0,0,0,9,-100,-2,5,0,0,0,0,9,-100,-2,11,0,0,0,0,9,-100,-3,0,0,0,0,9,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-5,11,5,1,0,1,7,-100,-3,0,0,0,0,11,-3,13,3,0,0,0,0,0,0,3,-100,-3,0,0,0,0,11,-2,7,0,0,0,0,0,0,0,0,0,9,-100,-3,0,0,0,0,11,11,3,0,5,11,-1,13,9,1,0,0,0,3,-100,-3,0,0,0,0,3,0,1,11,-6,1,0,0,0,13,-100,-3,0,0,0,0,0,5,-8,11,0,0,0,11,-100,-3,0,0,0,0,11,-10,0,0,0,7,-100,-3,0,0,0,0,13,-10,0,0,0,7,-100,-3,0,0,0,0,11,-10,0,0,0,7,-100,-3,0,0,0,0,11,-10,0,0,0,7,-100,-3,0,0,0,0,13,-10,0,0,0,9,-100,-3,0,0,0,0,13,-10,0,0,0,9,-100,-3,0,0,0,0,-11,0,0,0,11,-100,-3,0,0,0,1,-11,0,0,0,13,-100,-3,0,0,0,1,-11,0,0,0,13,-100,-3,0,0,0,3,-11,0,0,0,-100,-3,0,0,0,3,-11,0,0,0,-100,-3,0,0,0,3,-11,0,0,0,-100,-3,0,0,0,3,-10,13,0,0,0,13,-100,-3,0,0,0,1,-10,13,0,0,0,11,-100,-2,9,0,0,0,0,-10,11,0,0,0,5,-100,-1,7,0,0,0,0,0,5,13,-7,13,3,0,0,0,0,7,-100,5,0,0,0,0,0,0,0,0,3,-5,1,0,0,0,0,0,0,1,3,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt8[] = { -100,-100,-100,-100,-3,5,1,0,3,11,-100,-2,7,0,0,0,0,0,11,-100,-2,1,0,0,0,0,0,5,-100,-2,0,0,0,0,0,0,5,-100,-2,5,0,0,0,0,0,11,-100,-3,7,0,0,3,9,-100,-4,13,-100,-100,-100,-100,-100,-100,-100,-4,11,3,0,9,-100,-2,9,3,0,0,0,9,-100,11,1,0,0,0,0,0,7,-100,1,0,0,0,0,0,0,7,-100,1,0,0,0,0,0,0,9,-100,-1,11,0,0,0,0,0,9,-100,-2,7,0,0,0,0,11,-100,-3,0,0,0,0,13,-100,-3,1,0,0,0,-100,-3,1,0,0,0,13,-100,-3,1,0,0,0,13,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-2,13,0,0,0,0,7,-100,-2,13,0,0,0,0,1,-100,-2,7,0,0,0,0,0,9,-100,7,0,0,0,0,0,0,0,0,3,-100,9,5,1,1,0,0,1,1,3,5,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt9[] = { -100,-100,-100,-100,-6,5,0,1,5,13,-100,-5,5,0,0,0,0,1,-100,-5,1,0,0,0,0,0,13,-100,-5,0,0,0,0,0,0,-100,-5,5,0,0,0,0,3,-100,-6,7,1,0,5,13,-100,-100,-100,-100,-100,-100,-100,-100,-6,13,7,3,0,13,-100,-5,7,0,0,0,0,11,-100,-3,7,1,0,0,0,0,0,11,-100,-2,13,0,0,0,0,0,0,0,11,-100,-3,11,3,0,0,0,0,0,11,-100,-5,9,0,0,0,0,11,-100,-6,1,0,0,0,11,-100,-6,3,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,5,0,0,0,11,-100,-6,3,0,0,0,11,-100,-6,3,0,0,0,11,-100,-6,1,0,0,0,11,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,13,-100,-6,1,0,0,0,-100,-6,1,0,0,0,-100,-6,1,0,0,1,-100,-6,1,0,0,3,-100,-6,0,0,0,5,-100,-6,0,0,0,7,-100,-6,0,0,0,11,-100,11,0,0,0,5,5,0,0,5,-100,3,0,0,0,0,0,0,3,-100,0,0,0,0,0,0,0,13,-100,1,0,0,0,0,0,11,-100,13,3,0,0,3,11,-100,-100,-101 };
|
||||
static int8_t lt10[] = { -100,-100,-100,-100,-6,9,1,13,-100,-3,13,5,0,0,0,11,-100,-1,13,5,0,0,0,0,0,11,-100,13,1,0,0,0,0,0,0,11,-100,3,0,0,0,0,0,0,0,11,-100,11,3,0,0,0,0,0,0,11,-100,-2,13,0,0,0,0,0,11,-100,-3,9,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-7,3,0,0,0,0,0,0,0,0,0,3,-100,-4,0,0,0,0,11,-7,5,0,0,0,0,0,0,0,1,7,13,-100,-4,0,0,0,0,11,-8,9,0,0,0,1,9,-100,-4,0,0,0,0,11,-7,13,1,0,0,7,-100,-4,0,0,0,0,11,-7,5,0,3,13,-100,-4,0,0,0,0,11,-6,5,0,5,-100,-4,0,0,0,0,11,-5,5,1,11,-100,-4,0,0,0,0,11,-3,11,3,1,-100,-4,0,0,0,0,11,-1,11,3,0,0,1,-100,-4,0,0,0,0,11,9,0,0,0,0,0,11,-100,-4,0,0,0,0,0,0,1,0,0,0,0,3,-100,-4,0,0,0,0,0,9,-1,11,1,0,0,0,9,-100,-4,0,0,0,0,5,-4,3,0,0,0,11,-100,-4,0,0,0,0,11,-4,13,1,0,0,0,13,-100,-4,0,0,0,0,11,-5,11,0,0,0,1,13,-100,-4,0,0,0,0,11,-6,3,0,0,0,3,-100,-4,0,0,0,0,11,-6,11,0,0,0,0,7,-100,-4,0,0,0,0,11,-7,3,0,0,0,0,7,-100,-3,13,0,0,0,0,11,-7,13,0,0,0,0,0,7,-100,-2,13,3,0,0,0,0,7,-7,9,0,0,0,0,0,0,3,11,-100,-1,1,0,0,0,0,0,0,0,0,1,3,-4,0,0,0,0,0,0,0,0,0,0,3,-100,-1,7,1,0,0,0,0,0,0,0,0,7,-4,3,0,0,0,0,0,0,1,1,5,9,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt11[] = { -100,-100,-100,-6,11,7,11,-100,-4,11,3,0,0,5,-100,-3,5,0,0,0,0,5,-100,-1,11,1,0,0,0,0,0,7,-100,7,0,0,0,0,0,0,0,7,-100,0,0,0,0,0,0,0,0,9,-100,7,0,0,0,0,0,0,0,9,-100,-2,9,1,0,0,0,0,9,-100,-3,11,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,7,-100,-3,5,0,0,0,0,0,13,-100,-1,9,1,0,0,0,0,0,0,0,1,9,-100,-1,5,1,0,0,0,0,0,0,0,1,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt12[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-5,11,5,0,-21,7,1,0,3,9,-100,-4,7,0,0,0,13,-4,11,5,1,1,0,1,7,-7,11,3,0,0,0,0,0,5,-100,-2,11,1,0,0,0,0,11,-2,9,1,0,0,0,0,0,0,0,9,-4,13,5,0,0,0,0,0,0,0,0,7,-100,13,3,0,0,0,0,0,0,7,13,3,0,0,0,1,0,0,0,0,0,0,7,-1,13,7,0,0,0,0,0,0,0,0,0,0,0,11,-100,3,0,0,0,0,0,0,0,1,0,0,5,11,-3,11,0,0,0,0,0,0,0,3,9,13,13,-3,7,0,0,0,0,5,-100,13,3,0,0,0,0,0,0,0,7,13,-6,3,0,0,0,0,0,9,-8,5,0,0,0,1,-100,-2,11,0,0,0,0,0,3,-8,9,0,0,0,0,7,-9,11,0,0,0,0,-100,-3,3,0,0,0,0,7,-8,13,0,0,0,0,-10,11,0,0,0,0,-100,-3,7,0,0,0,0,11,-9,0,0,0,0,-10,11,0,0,0,1,-100,-3,11,0,0,0,0,11,-9,0,0,0,0,-10,11,0,0,0,3,-100,-3,13,0,0,0,0,11,-8,13,0,0,0,0,-10,11,0,0,0,5,-100,-3,13,0,0,0,0,11,-8,11,0,0,0,0,-10,11,0,0,0,5,-100,-4,0,0,0,0,13,-8,9,0,0,0,0,-10,11,0,0,0,5,-100,-4,0,0,0,0,13,-8,11,0,0,0,0,-10,11,0,0,0,3,-100,-4,0,0,0,0,13,-8,11,0,0,0,0,-10,11,0,0,0,0,-100,-3,13,0,0,0,1,-9,13,0,0,0,0,-10,11,0,0,0,0,-100,-3,11,0,0,0,13,-10,0,0,0,0,-10,11,0,0,0,0,-100,-4,0,0,0,11,-10,0,0,0,0,-10,11,0,0,0,0,-100,-3,13,0,0,0,3,-9,13,0,0,0,0,13,-9,9,0,0,0,0,-100,-3,7,0,0,0,0,13,-8,11,0,0,0,0,11,-9,7,0,0,0,0,13,-100,-3,3,0,0,0,0,9,-8,5,0,0,0,0,5,-9,5,0,0,0,0,7,-100,-1,13,3,0,0,0,0,0,1,11,-6,9,0,0,0,0,0,0,3,-7,11,1,0,0,0,0,1,13,-100,11,0,0,0,0,0,0,0,0,0,3,-4,3,0,0,0,0,0,0,0,0,5,-5,1,0,0,0,0,0,0,0,0,9,-100,13,1,0,0,0,0,0,0,0,1,9,-4,1,0,0,0,0,0,0,0,1,5,-5,1,0,0,0,0,0,0,0,0,7,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt13[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-3,13,7,3,0,13,-5,13,7,1,0,0,3,7,-100,-2,5,0,0,0,0,-4,13,3,0,0,0,0,0,0,0,7,-100,7,1,0,0,0,0,0,-3,7,0,0,0,0,0,0,0,0,0,0,13,-100,1,0,0,0,0,0,0,13,9,1,0,5,11,13,-1,11,3,0,0,0,0,9,-100,13,3,0,0,0,0,0,1,1,7,-7,3,0,0,0,3,-100,-2,1,0,0,0,0,7,-9,13,0,0,0,1,-100,-2,7,0,0,0,0,-11,1,0,0,0,-100,-2,9,0,0,0,0,-11,1,0,0,0,13,-100,-2,11,0,0,0,0,-11,3,0,0,0,13,-100,-2,11,0,0,0,0,-11,5,0,0,0,11,-100,-2,11,0,0,0,0,-11,3,0,0,0,11,-100,-2,11,0,0,0,0,-11,1,0,0,0,11,-100,-2,11,0,0,0,0,-11,0,0,0,0,11,-100,-2,11,0,0,0,0,-11,0,0,0,0,11,-100,-2,11,0,0,0,0,-11,1,0,0,0,11,-100,-2,11,0,0,0,0,-11,3,0,0,0,11,-100,-2,11,0,0,0,0,-11,3,0,0,0,11,-100,-2,11,0,0,0,0,13,-10,5,0,0,0,11,-100,-2,11,0,0,0,0,13,-10,5,0,0,0,11,-100,-2,11,0,0,0,0,9,-10,5,0,0,0,9,-100,-2,7,0,0,0,0,5,-10,3,0,0,0,7,-100,-1,13,1,0,0,0,0,1,11,-7,11,5,0,0,0,0,0,3,9,-100,-1,1,0,0,0,0,0,0,0,0,3,-4,3,0,0,0,0,0,0,0,0,0,3,-100,-1,0,0,0,0,0,0,0,0,0,3,-4,5,1,0,0,0,0,0,0,0,0,1,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt14[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-7,13,7,3,1,0,0,1,5,9,-100,-6,7,0,0,0,0,0,0,0,0,0,1,7,-100,-4,11,1,0,0,1,9,13,-1,13,11,5,0,0,0,3,13,-100,-3,11,0,0,0,3,13,-6,13,1,0,0,0,13,-100,-2,11,0,0,0,1,13,-8,13,0,0,0,5,-100,-2,0,0,0,0,9,-10,5,0,0,0,11,-100,-1,7,0,0,0,1,-11,13,0,0,0,1,-100,-1,1,0,0,0,5,-12,1,0,0,0,9,-100,11,0,0,0,0,11,-12,5,0,0,0,3,-100,7,0,0,0,0,13,-12,9,0,0,0,0,-100,3,0,0,0,0,13,-12,11,0,0,0,0,-100,1,0,0,0,0,-13,11,0,0,0,1,-100,0,0,0,0,0,-13,11,0,0,0,1,-100,0,0,0,0,0,13,-12,11,0,0,0,0,-100,1,0,0,0,0,13,-12,9,0,0,0,1,-100,5,0,0,0,0,11,-12,5,0,0,0,3,-100,9,0,0,0,0,9,-12,3,0,0,0,7,-100,-1,1,0,0,0,5,-12,0,0,0,0,11,-100,-1,9,0,0,0,3,-11,13,0,0,0,3,-100,-2,3,0,0,0,13,-10,7,0,0,0,11,-100,-2,13,1,0,0,3,-9,13,0,0,0,7,-100,-3,13,1,0,0,3,13,-6,13,1,0,0,5,-100,-4,13,1,0,0,1,7,13,-3,9,0,0,0,7,-100,-6,7,0,0,0,0,0,0,0,0,0,3,11,-100,-7,13,7,3,0,0,0,0,3,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt15[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,11,7,-100,-4,11,3,0,0,7,11,5,3,0,0,0,1,5,9,-100,-2,11,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,-100,13,5,0,0,0,0,0,0,0,1,7,11,13,-1,13,3,0,0,0,5,-100,1,0,0,0,0,0,0,0,3,-7,7,0,0,0,7,-100,1,0,0,0,0,0,0,0,11,-8,7,0,0,0,13,-100,-1,11,5,0,0,0,0,0,11,-9,1,0,0,3,-100,-3,7,0,0,0,0,11,-9,5,0,0,0,11,-100,-3,9,0,0,0,0,11,-9,9,0,0,0,5,-100,-3,11,0,0,0,0,11,-9,11,0,0,0,0,13,-100,-3,11,0,0,0,0,11,-9,13,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,13,-100,-4,0,0,0,0,11,-10,0,0,0,0,13,-100,-4,0,0,0,0,13,-10,0,0,0,0,-100,-4,0,0,0,9,-11,0,0,0,3,-100,-4,0,0,0,3,-11,0,0,0,9,-100,-4,0,0,0,0,13,-10,0,0,0,13,-100,-4,0,0,0,0,11,-9,5,0,0,0,-100,-4,0,0,0,0,11,-8,7,0,0,0,7,-100,-4,0,0,0,0,5,-7,9,0,0,0,3,-100,-4,0,0,0,0,0,3,11,13,-3,9,0,0,0,1,-100,-4,0,0,0,0,5,7,0,0,0,1,1,0,0,0,1,13,-100,-4,0,0,0,0,11,-2,9,5,1,0,0,3,7,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,7,-100,-4,0,0,0,0,3,-100,-3,7,0,0,0,0,0,9,-100,-1,5,0,0,0,0,0,0,0,0,0,0,5,-100,-1,3,1,0,0,0,0,0,0,0,0,0,5,-100,-101 };
|
||||
static int8_t lt16[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-19,7,11,-100,-6,11,5,1,0,0,1,5,11,-4,5,0,3,-100,-4,13,3,0,0,0,0,0,0,0,0,1,11,13,5,0,0,1,-100,-3,13,1,0,0,1,5,11,-3,11,3,0,0,0,0,0,3,-100,-2,13,1,0,0,3,-8,3,0,0,0,0,5,-100,-1,13,1,0,0,0,13,-8,7,0,0,0,0,5,-100,-1,3,0,0,0,5,-9,11,0,0,0,0,7,-100,9,0,0,0,0,11,-9,13,0,0,0,0,9,-100,3,0,0,0,0,-10,13,0,0,0,0,9,-100,1,0,0,0,1,-11,0,0,0,0,9,-100,0,0,0,0,3,-11,0,0,0,0,11,-100,0,0,0,0,5,-11,0,0,0,0,11,-100,0,0,0,0,9,-11,0,0,0,0,11,-100,0,0,0,0,11,-11,0,0,0,0,11,-100,0,0,0,0,11,-11,0,0,0,0,11,-100,1,0,0,0,11,-11,0,0,0,0,11,-100,3,0,0,0,9,-11,0,0,0,0,11,-100,7,0,0,0,5,-11,0,0,0,0,11,-100,11,0,0,0,0,-11,0,0,0,0,11,-100,-1,1,0,0,0,7,-9,11,0,0,0,0,11,-100,-1,9,0,0,0,0,13,-8,9,0,0,0,0,11,-100,-2,3,0,0,0,1,13,-7,5,0,0,0,0,11,-100,-2,13,3,0,0,0,1,9,13,-3,13,7,0,0,0,0,0,11,-100,-4,9,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,11,-100,-6,11,7,3,1,0,0,5,9,-1,13,0,0,0,0,11,-100,-16,0,0,0,0,13,-100,-16,0,0,0,0,13,-100,-16,0,0,0,0,13,-100,-16,0,0,0,0,13,-100,-15,13,0,0,0,0,13,-100,-15,9,0,0,0,0,11,-100,-15,1,0,0,0,0,5,-100,-12,7,5,1,0,0,0,0,0,0,1,3,9,-100,-11,13,1,0,0,0,0,0,0,0,0,0,0,7,-100,-101 };
|
||||
static int8_t lt17[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-3,13,5,0,3,-5,9,3,1,0,0,3,-100,-1,11,3,0,0,0,0,-3,7,0,0,0,0,0,0,0,5,-100,9,0,0,0,0,0,0,-2,3,0,0,0,0,0,0,0,0,1,-100,0,0,0,0,0,0,0,11,3,0,0,0,0,0,0,0,0,0,1,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-100,-1,7,0,0,0,0,0,0,7,13,-2,11,7,3,1,3,11,-100,-2,3,0,0,0,0,3,-100,-2,7,0,0,0,0,9,-100,-2,11,0,0,0,0,13,-100,-2,13,0,0,0,0,-100,-3,0,0,0,0,-100,-3,0,0,0,0,13,-100,-3,0,0,0,0,13,-100,-3,0,0,0,0,13,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,11,-100,-3,0,0,0,0,9,-100,-1,13,3,0,0,0,0,1,13,-100,3,0,0,0,0,0,0,0,0,0,0,13,-100,5,1,0,0,0,0,0,0,0,0,3,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt18[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-3,13,7,1,0,1,3,9,11,9,9,13,-100,-2,13,1,0,0,0,0,0,0,0,0,0,5,-100,-2,1,0,5,13,-1,13,11,3,0,0,0,1,-100,-1,9,0,1,-6,9,0,0,0,13,-100,-1,3,0,9,-7,11,1,0,9,-100,-1,0,0,-9,13,1,5,-100,-1,0,0,11,-9,13,11,-100,13,0,0,1,13,-100,13,0,0,0,1,9,-100,-1,0,0,0,0,0,0,5,9,-100,-1,5,0,0,0,0,0,0,0,1,7,13,-100,-1,13,0,0,0,0,0,0,0,0,0,0,9,-100,-2,13,1,0,0,0,0,0,0,0,0,0,7,-100,-4,11,5,0,0,0,0,0,0,0,0,7,-100,-7,9,5,0,0,0,0,0,0,13,-100,-9,13,7,0,0,0,0,7,-100,-11,13,3,0,0,3,-100,-13,0,0,0,-100,7,5,-11,1,0,0,-100,1,0,5,-10,1,0,3,-100,0,0,0,3,-9,0,0,9,-100,1,0,0,0,3,13,-6,5,0,3,-100,7,0,0,0,0,1,7,11,13,13,9,3,0,1,13,-100,13,0,0,0,0,0,0,0,0,0,0,0,3,13,-100,-1,5,3,9,7,3,1,0,0,1,5,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt19[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,5,0,5,-100,-5,13,0,0,0,7,-100,-5,7,0,0,0,9,-100,-5,3,0,0,0,13,-100,-4,11,0,0,0,0,-100,-4,3,0,0,0,0,-100,-3,5,0,0,0,0,1,-100,-2,3,0,0,0,0,0,7,-100,13,1,0,0,0,0,0,0,1,11,-100,3,0,0,0,0,0,0,0,0,0,0,0,0,0,5,13,-100,1,0,0,0,0,0,0,0,0,0,0,0,0,0,5,-100,-3,9,0,0,0,0,7,13,-100,-4,0,0,0,0,11,-100,-4,1,0,0,0,11,-100,-4,1,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,0,0,0,0,11,-100,-4,1,0,0,0,11,-100,-4,3,0,0,0,11,-100,-4,5,0,0,0,11,-100,-4,3,0,0,0,11,-100,-4,3,0,0,0,11,-100,-4,1,0,0,0,9,-100,-4,0,0,0,0,5,-100,-4,0,0,0,0,1,-100,-4,1,0,0,0,0,11,-100,-4,3,0,0,0,0,1,13,-1,9,5,1,3,-100,-4,9,0,0,0,0,0,0,0,0,0,0,5,-100,-5,5,0,0,0,0,0,0,0,0,5,-100,-6,9,3,1,0,0,1,5,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt20[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-4,13,9,1,0,13,-11,11,5,1,5,-100,-2,11,3,0,0,0,0,11,-8,11,5,0,0,0,0,1,-100,13,3,0,0,0,0,0,0,11,-6,7,1,0,0,0,0,0,0,7,-100,5,0,0,0,0,0,0,0,11,-5,5,0,0,0,0,0,0,0,0,11,-100,11,1,0,0,0,0,0,0,11,-5,9,0,0,0,0,0,0,0,0,11,-100,-2,11,1,0,0,0,0,11,-6,13,7,3,0,0,0,0,0,11,-100,-3,9,0,0,0,0,11,-9,9,0,0,0,0,11,-100,-3,11,0,0,0,0,11,-10,0,0,0,0,11,-100,-3,13,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,0,0,0,0,11,-10,0,0,0,0,11,-100,-4,1,0,0,0,11,-9,13,0,0,0,0,11,-100,-4,1,0,0,0,11,-9,5,0,0,0,0,11,-100,-4,5,0,0,0,7,-8,7,0,0,0,0,0,11,-100,-4,7,0,0,0,0,13,-5,13,5,0,0,0,0,0,0,11,-100,-4,13,0,0,0,0,1,11,-1,13,11,5,0,0,7,5,0,0,0,0,3,13,-100,-5,3,0,0,0,0,0,0,0,0,0,3,13,-2,0,0,0,0,0,0,7,-100,-5,11,0,0,0,0,0,0,0,1,9,-4,0,0,0,0,0,0,0,-100,-6,13,5,1,0,1,3,9,-6,3,1,3,7,9,11,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt21[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-6,13,9,1,3,13,-5,13,1,0,0,0,0,1,3,9,-100,1,0,0,0,0,0,0,0,0,0,1,-5,1,0,0,0,0,0,0,0,0,9,-100,3,0,0,0,0,0,0,0,0,0,5,-5,3,0,0,0,0,0,0,0,0,13,-100,-1,9,3,0,0,0,0,0,5,13,-7,13,9,0,0,0,0,1,11,-100,-3,7,0,0,0,0,-11,7,0,0,5,-100,-4,0,0,0,0,9,-10,9,0,5,-100,-4,5,0,0,0,1,-10,5,0,11,-100,-4,11,0,0,0,0,9,-9,0,1,-100,-5,1,0,0,0,3,-8,9,0,7,-100,-5,7,0,0,0,0,13,-7,3,0,13,-100,-5,13,0,0,0,0,7,-6,13,0,3,-100,-6,3,0,0,0,1,-6,7,0,11,-100,-6,9,0,0,0,0,9,-5,0,1,-100,-6,13,0,0,0,0,3,-4,7,0,7,-100,-7,5,0,0,0,0,11,-3,1,0,13,-100,-7,11,0,0,0,0,1,-2,9,0,5,-100,-8,1,0,0,0,0,5,-1,1,0,11,-100,-8,7,0,0,0,0,0,0,0,3,-100,-8,13,0,0,0,0,0,0,0,9,-100,-9,3,0,0,0,0,0,1,-100,-9,9,0,0,0,0,0,7,-100,-10,0,0,0,0,0,13,-100,-10,5,0,0,0,1,-100,-10,13,1,0,0,7,-100,-11,11,1,5,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt22[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-29,13,-100,5,0,0,1,1,1,3,3,5,7,-3,7,0,0,0,0,0,0,0,0,0,11,-4,3,0,0,0,0,0,0,1,3,11,-100,5,0,0,0,0,0,0,0,1,7,-3,9,0,0,0,0,0,0,0,0,1,11,-4,9,1,0,0,0,0,0,0,1,13,-100,-1,13,5,0,0,0,0,0,13,-5,13,5,0,0,0,0,0,3,-8,9,0,0,0,0,5,-100,-3,5,0,0,0,0,-8,11,0,0,0,0,9,-9,9,0,0,9,-100,-4,1,0,0,0,13,-8,11,0,0,0,3,-10,0,3,-100,-4,7,0,0,0,11,-8,13,0,0,0,0,13,-8,9,0,11,-100,-4,13,0,0,0,7,-8,11,0,0,0,0,7,-8,1,1,-100,-5,5,0,0,1,-8,7,0,0,0,0,3,-8,5,11,-100,-5,11,0,0,0,9,-7,1,0,0,0,0,0,13,-100,-6,0,0,0,3,-6,9,0,3,13,0,0,0,7,-6,5,-100,-6,3,0,0,0,13,-5,1,0,11,-1,3,0,0,3,-6,1,-100,-6,9,0,0,0,9,-4,11,0,3,-2,7,0,0,0,13,-4,11,1,-100,-6,13,0,0,0,3,-4,5,0,9,-2,13,0,0,0,7,-4,5,3,-100,-7,3,0,0,0,13,-3,1,1,-4,0,0,0,1,-4,1,7,-100,-7,9,0,0,0,5,-2,13,0,7,-4,5,0,0,0,9,-2,9,0,13,-100,-8,1,0,0,0,13,-1,7,1,-5,11,0,0,0,1,-2,1,3,-100,-8,7,0,0,0,1,13,1,5,-6,1,0,0,0,13,9,0,9,-100,-8,13,0,0,0,0,0,0,11,-6,7,0,0,0,1,0,1,-100,-9,3,0,0,0,0,3,-7,13,0,0,0,0,0,9,-100,-9,9,0,0,0,0,5,-8,3,0,0,0,0,13,-100,-9,13,0,0,0,0,11,-8,9,0,0,0,1,-100,-10,3,0,0,0,-10,3,0,0,5,-100,-10,11,0,0,7,-10,13,1,1,13,-100,-11,11,11,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt23[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-16,13,13,-1,13,9,5,1,0,1,5,13,-100,-1,3,0,0,0,0,0,0,0,0,1,7,-4,1,0,0,0,0,0,0,0,0,0,1,-100,-1,1,0,0,0,0,0,0,0,0,1,11,-4,7,0,0,0,0,0,0,0,0,0,5,-100,-2,13,7,0,0,0,0,0,0,13,-6,13,5,0,0,0,0,5,9,13,-100,-4,13,3,0,0,0,0,3,-7,13,0,0,5,13,-100,-6,3,0,0,0,0,5,-6,7,0,7,-100,-7,3,0,0,0,0,11,-4,11,0,9,-100,-8,5,0,0,0,1,-3,11,0,7,-100,-9,3,0,0,0,1,11,11,0,7,-100,-9,13,1,0,0,0,0,0,7,-100,-10,13,1,0,0,0,0,9,-100,-11,11,0,0,0,0,1,-100,-12,0,0,0,0,0,7,-100,-11,9,0,0,0,0,0,0,11,-100,-10,9,0,5,13,3,0,0,0,1,13,-100,-9,11,0,3,-2,13,1,0,0,0,1,13,-100,-8,11,0,3,13,-3,13,1,0,0,0,1,13,-100,-7,9,0,1,13,-5,11,0,0,0,0,1,13,-100,-6,9,0,0,7,-7,9,0,0,0,0,1,11,-100,-5,5,0,0,0,13,-8,7,0,0,0,0,0,9,-100,-3,13,3,0,0,0,0,13,-8,13,0,0,0,0,0,0,5,-100,9,3,1,0,0,0,0,0,0,1,11,-6,11,1,0,0,0,0,0,0,0,1,3,13,-100,3,0,0,0,0,0,0,0,0,0,3,-6,11,5,3,1,0,0,0,1,1,3,5,-100,13,13,13,13,-100,-100,-100,-100,-100,-100,-100,-100,-100,-101 };
|
||||
static int8_t lt24[] = { -100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-1,13,13,-2,13,13,11,11,11,13,-6,11,11,11,11,11,11,11,11,13,-100,3,0,0,0,0,0,0,0,0,0,0,3,-4,1,0,0,0,0,0,0,0,0,1,-100,7,0,0,0,0,0,0,0,0,0,0,5,-4,3,0,0,0,0,0,0,0,0,9,-100,-2,11,5,0,0,0,0,0,0,11,-6,11,0,0,0,0,1,7,13,-100,-4,11,0,0,0,0,0,-8,9,0,0,1,13,-100,-5,7,0,0,0,0,13,-7,9,0,0,13,-100,-6,1,0,0,0,9,-7,5,0,5,-100,-6,7,0,0,0,3,-7,1,0,13,-100,-6,13,0,0,0,0,13,-5,11,0,1,-100,-7,5,0,0,0,7,-5,7,0,7,-100,-7,11,0,0,0,3,-5,1,0,11,-100,-8,1,0,0,0,13,-3,13,0,3,-100,-8,7,0,0,0,7,-3,7,0,9,-100,-8,13,0,0,0,3,-3,1,1,-100,-9,5,0,0,0,13,-1,9,0,7,-100,-9,11,0,0,0,3,13,1,0,13,-100,-10,1,0,0,0,0,0,3,-100,-10,9,0,0,0,0,0,9,-100,-11,1,0,0,0,1,-100,-11,5,0,0,0,7,-100,-11,9,0,0,0,13,-100,-11,13,0,0,3,-100,-12,0,0,9,-100,-12,0,1,-100,-11,13,0,7,-100,-11,7,0,11,-100,-11,1,0,-100,-2,7,0,1,7,-4,11,0,3,-100,-1,11,0,0,0,0,1,9,13,11,1,0,9,-100,-1,3,0,0,0,0,0,0,0,0,0,3,-100,-1,0,0,0,0,0,0,0,0,0,1,13,-100,-1,7,0,0,0,0,0,0,0,1,13,-100,-2,9,3,0,0,1,3,7,-100,-101 };
|
||||
static int8_t *lt[] = { lt0,lt1,lt2,lt3,lt0,lt5,lt0,lt7,lt8,lt9,lt10,lt11,lt12,lt13,lt14,lt15,lt16,lt17,lt18,lt19,lt20,lt21,lt22,lt23,lt24, };
|
||||
|
||||
const int gifsize=17646;
|
||||
|
||||
void makegif(unsigned char im[70*200], unsigned char gif[17646]) {
|
||||
// tag ; widthxheight ; GCT:0:0:7 ; bgcolor + aspect // GCT
|
||||
// Image Separator // left x top // widthxheight // Flags
|
||||
// LZW code size
|
||||
memcpy(gif,"GIF89a" "\xc8\0\x46\0" "\x83" "\0\0"
|
||||
"\x00\x00\x00"
|
||||
"\x10\x10\x10"
|
||||
"\x20\x20\x20"
|
||||
"\x30\x30\x30"
|
||||
"\x40\x40\x40"
|
||||
"\x50\x50\x50"
|
||||
"\x60\x60\x60"
|
||||
"\x70\x70\x70"
|
||||
"\x80\x80\x80"
|
||||
"\x90\x90\x90"
|
||||
"\xa0\xa0\xa0"
|
||||
"\xb0\xb0\xb0"
|
||||
"\xc0\xc0\xc0"
|
||||
"\xd0\xd0\xd0"
|
||||
"\xe0\xe0\xe0"
|
||||
"\xff\xff\xff"
|
||||
"," "\0\0\0\0" "\xc8\0\x46\0" "\0" "\x04",13+48+10+1);
|
||||
|
||||
int x,y;
|
||||
unsigned char *i=im;
|
||||
unsigned char *p=gif+13+48+10+1;
|
||||
for(y=0;y<70;y++) {
|
||||
*p++=250; // Data length 5*50=250
|
||||
for(x=0;x<50;x++)
|
||||
{
|
||||
unsigned char a=i[0]>>4,b=i[1]>>4,c=i[2]>>4,d=i[3]>>4;
|
||||
|
||||
p[0]=16|(a<<5); // bbb10000
|
||||
p[1]=(a>>3)|64|(b<<7); // b10000xb
|
||||
p[2]=b>>1; // 0000xbbb
|
||||
p[3]=1|(c<<1); // 00xbbbb1
|
||||
p[4]=4|(d<<3); // xbbbb100
|
||||
i+=4;
|
||||
p+=5;
|
||||
}
|
||||
}
|
||||
|
||||
// Data length // End of LZW (b10001) // Terminator // GIF End
|
||||
memcpy(gif+gifsize-4,"\x01" "\x11" "\x00" ";",4);
|
||||
}
|
||||
|
||||
static const int8_t sw[200]={0, 4, 8, 12, 16, 20, 23, 27, 31, 35, 39, 43, 47, 50, 54, 58, 61, 65, 68, 71, 75, 78, 81, 84, 87, 90, 93, 96, 98, 101, 103, 105, 108, 110, 112, 114, 115, 117, 119, 120, 121, 122, 123, 124, 125, 126, 126, 127, 127, 127, 127, 127, 127, 127, 126, 126, 125, 124, 123, 122, 121, 120, 119, 117, 115, 114, 112, 110, 108, 105, 103, 101, 98, 96, 93, 90, 87, 84, 81, 78, 75, 71, 68, 65, 61, 58, 54, 50, 47, 43, 39, 35, 31, 27, 23, 20, 16, 12, 8, 4, 0, -4, -8, -12, -16, -20, -23, -27, -31, -35, -39, -43, -47, -50, -54, -58, -61, -65, -68, -71, -75, -78, -81, -84, -87, -90, -93, -96, -98, -101, -103, -105, -108, -110, -112, -114, -115, -117, -119, -120, -121, -122, -123, -124, -125, -126, -126, -127, -127, -127, -127, -127, -127, -127, -126, -126, -125, -124, -123, -122, -121, -120, -119, -117, -115, -114, -112, -110, -108, -105, -103, -101, -98, -96, -93, -90, -87, -84, -81, -78, -75, -71, -68, -65, -61, -58, -54, -50, -47, -43, -39, -35, -31, -27, -23, -20, -16, -12, -8, -4};
|
||||
|
||||
|
||||
#define MAX(x,y) ((x>y)?(x):(y))
|
||||
|
||||
static int letter(int n, int pos, unsigned char im[70*200], unsigned char swr[200], uint8_t s1, uint8_t s2) {
|
||||
int8_t *p=lt[n];
|
||||
unsigned char *r=im+200*16+pos;
|
||||
unsigned char *i=r;
|
||||
int sk1=s1+pos;
|
||||
int sk2=s2+pos;
|
||||
int mpos=pos;
|
||||
int row=0;
|
||||
for(;*p!=-101;p++) {
|
||||
if(*p<0) {
|
||||
if(*p==-100) { r+=200; i=r; sk1=s1+pos; row++; continue; }
|
||||
i+=-*p;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sk1>=200) sk1=sk1%200;
|
||||
int skew=sw[sk1]/16;
|
||||
sk1+=(swr[pos+i-r]&0x1)+1;
|
||||
|
||||
if(sk2>=200) sk2=sk2%200;
|
||||
int skewh=sw[sk2]/70;
|
||||
sk2+=(swr[row]&0x1);
|
||||
|
||||
unsigned char *x=i+skew*200+skewh;
|
||||
mpos=MAX(mpos,pos+i-r);
|
||||
|
||||
if((x-im)<70*200) *x=(*p)<<4;
|
||||
i++;
|
||||
}
|
||||
return mpos;
|
||||
}
|
||||
|
||||
#define NDOTS 100
|
||||
|
||||
uint32_t dr[NDOTS];
|
||||
|
||||
static void line(unsigned char im[70*200], unsigned char swr[200], uint8_t s1) {
|
||||
int x;
|
||||
int sk1=s1;
|
||||
for(x=0;x<199;x++) {
|
||||
if(sk1>=200) sk1=sk1%200;
|
||||
int skew=sw[sk1]/16;
|
||||
sk1+=swr[x]&0x3+1;
|
||||
unsigned char *i= im+(200*(45+skew)+x);
|
||||
i[0]=0; i[1]=0; i[200]=0; i[201]=0;
|
||||
}
|
||||
}
|
||||
|
||||
static void dots(unsigned char im[70*200]) {
|
||||
int n;
|
||||
for(n=0;n<NDOTS;n++) {
|
||||
uint32_t v=dr[n];
|
||||
unsigned char *i=im+v%(200*67);
|
||||
|
||||
i[0]=0xff;
|
||||
i[1]=0xff;
|
||||
i[2]=0xff;
|
||||
i[200]=0xff;
|
||||
i[201]=0xff;
|
||||
i[202]=0xff;
|
||||
}
|
||||
}
|
||||
static void blur(unsigned char im[70*200]) {
|
||||
unsigned char *i=im;
|
||||
int x,y;
|
||||
for(y=0;y<68;y++) {
|
||||
for(x=0;x<198;x++) {
|
||||
unsigned int c11=*i,c12=i[1],c21=i[200],c22=i[201];
|
||||
*i++=((c11+c12+c21+c22)/4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void filter(unsigned char im[70*200]) {
|
||||
unsigned char om[70*200];
|
||||
unsigned char *i=im;
|
||||
unsigned char *o=om;
|
||||
|
||||
memset(om,0xff,sizeof(om));
|
||||
|
||||
int x,y;
|
||||
for(y=0;y<70;y++) {
|
||||
for(x=4;x<200-4;x++) {
|
||||
if(i[0]>0xf0 && i[1]<0xf0) { o[0]=0; o[1]=0; }
|
||||
else if(i[0]<0xf0 && i[1]>0xf0) { o[0]=0; o[1]=0; }
|
||||
|
||||
i++;
|
||||
o++;
|
||||
}
|
||||
}
|
||||
|
||||
memmove(im,om,sizeof(om));
|
||||
}
|
||||
|
||||
static const char *letters="abcdafahijklmnopqrstuvwxyz";
|
||||
|
||||
void captcha(unsigned char im[70*200], unsigned char l[6]) {
|
||||
|
||||
unsigned char swr[200];
|
||||
uint8_t s1, s2;
|
||||
|
||||
int i = 0;
|
||||
for (i = 0; i < 200; i++)
|
||||
swr[i] = rand() % 256;
|
||||
|
||||
for (i = 0; i < NDOTS*4; i++)
|
||||
((unsigned char*)dr)[i] = rand() % 256;
|
||||
|
||||
s1 = rand() % 256;
|
||||
s2 = rand() % 256;
|
||||
|
||||
memset(im,0xff,200*70); s1=s1&0x7f; s2=s2&0x3f; l[0]%=25; l[1]%=25; l[2]%=25; l[3]%=25; l[4]%=25; l[5]=0;
|
||||
int p=30; p=letter(l[0],p,im,swr,s1,s2); p=letter(l[1],p,im,swr,s1,s2); p=letter(l[2],p,im,swr,s1,s2); p=letter(l[3],p,im,swr,s1,s2); letter(l[4],p,im,swr,s1,s2);
|
||||
dots(im); blur(im); filter(im); line(im,swr,s1);
|
||||
l[0]=letters[l[0]]; l[1]=letters[l[1]]; l[2]=letters[l[2]]; l[3]=letters[l[3]]; l[4]=letters[l[4]];
|
||||
}
|
||||
|
||||
#ifdef CAPTCHA
|
||||
|
||||
int main() {
|
||||
char l[6];
|
||||
unsigned char im[70*200];
|
||||
unsigned char gif[gifsize];
|
||||
|
||||
captcha(im,l);
|
||||
makegif(im,gif);
|
||||
|
||||
write(1,gif,gifsize);
|
||||
write(2,l,5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
http://brokestream.com/captcha.html
|
||||
|
||||
Copyright (C) 2009 Ivan Tikhonov
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Ivan Tikhonov, kefeer@brokestream.com
|
||||
|
||||
*/
|
||||
131
src/tools/web_api/dep/smtp-client/COPYING
Normal file
131
src/tools/web_api/dep/smtp-client/COPYING
Normal file
@@ -0,0 +1,131 @@
|
||||
Creative Commons Legal Code
|
||||
CC0 1.0 Universal
|
||||
Official translations of this legal tool are available
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL
|
||||
SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT
|
||||
RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS.
|
||||
CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE
|
||||
INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES
|
||||
RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator and
|
||||
subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for the
|
||||
purpose of contributing to a commons of creative, cultural and scientific works
|
||||
("Commons") that the public can reliably and without fear of later claims of
|
||||
infringement build upon, modify, incorporate in other works, reuse and
|
||||
redistribute as freely as possible in any form whatsoever and for any purposes,
|
||||
including without limitation commercial purposes. These owners may contribute
|
||||
to the Commons to promote the ideal of a free culture and the further
|
||||
production of creative, cultural and scientific works, or to gain reputation
|
||||
or greater distribution for their Work in part through the use and efforts of
|
||||
others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any expectation
|
||||
of additional consideration or compensation, the person associating CC0 with a
|
||||
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
|
||||
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
|
||||
and publicly distribute the Work under its terms, with knowledge of his or her
|
||||
Copyright and Related Rights in the Work and the meaning and intended legal
|
||||
effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights.
|
||||
|
||||
A Work made available under CC0 may be protected by copyright and related
|
||||
or neighboring rights ("Copyright and Related Rights"). Copyright and
|
||||
Related Rights include, but are not limited to, the following:
|
||||
|
||||
the right to reproduce, adapt, distribute, perform, display, communicate,
|
||||
and translate a Work;
|
||||
|
||||
moral rights retained by the original author(s) and/or performer(s);
|
||||
|
||||
publicity and privacy rights pertaining to a person's image or likeness
|
||||
depicted in a Work;
|
||||
|
||||
rights protecting against unfair competition in regards to a Work, subject
|
||||
to the limitations in paragraph 4(a), below;
|
||||
|
||||
rights protecting the extraction, dissemination, use and reuse of data in
|
||||
a Work;
|
||||
|
||||
database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation thereof,
|
||||
including any amended or successor version of such directive); and
|
||||
|
||||
other similar, equivalent or corresponding rights throughout the world
|
||||
based on applicable law or treaty, and any national implementations
|
||||
thereof.
|
||||
|
||||
2. Waiver.
|
||||
|
||||
To the greatest extent permitted by, but not in contravention of, applicable
|
||||
law, Affirmer hereby overtly, fully, permanently, irrevocably and
|
||||
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
|
||||
and Related Rights and associated claims and causes of action, whether now
|
||||
known or unknown (including existing as well as future claims and causes of
|
||||
action), in the Work (i) in all territories worldwide, (ii) for the maximum
|
||||
duration provided by applicable law or treaty (including future time
|
||||
extensions), (iii) in any current or future medium and for any number of
|
||||
copies, and (iv) for any purpose whatsoever, including without limitation
|
||||
commercial, advertising or promotional purposes (the "Waiver"). Affirmer
|
||||
makes the Waiver for the benefit of each member of the public at large and
|
||||
to the detriment of Affirmer's heirs and successors, fully intending that
|
||||
such Waiver shall not be subject to revocation, rescission, cancellation,
|
||||
termination, or any other legal or equitable action to disrupt the quiet
|
||||
enjoyment of the Work by the public as contemplated by Affirmer's express
|
||||
Statement of Purpose.
|
||||
|
||||
3. Public License Fallback.
|
||||
|
||||
Should any part of the Waiver for any reason be judged legally invalid or
|
||||
ineffective under applicable law, then the Waiver shall be preserved to the
|
||||
maximum extent permitted taking into account Affirmer's express Statement of
|
||||
Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby
|
||||
grants to each affected person a royalty-free, non transferable, non
|
||||
sublicensable, non exclusive, irrevocable and unconditional license to
|
||||
exercise Affirmer's Copyright and Related Rights in the Work (i) in all
|
||||
territories worldwide, (ii) for the maximum duration provided by applicable
|
||||
law or treaty (including future time extensions), (iii) in any current or
|
||||
future medium and for any number of copies, and (iv) for any purpose
|
||||
whatsoever, including without limitation commercial, advertising or
|
||||
promotional purposes (the "License"). The License shall be deemed effective
|
||||
as of the date CC0 was applied by Affirmer to the Work. Should any part of
|
||||
the License for any reason be judged legally invalid or ineffective under
|
||||
applicable law, such partial invalidity or ineffectiveness shall not
|
||||
invalidate the remainder of the License, and in such case Affirmer hereby
|
||||
affirms that he or she will not (i) exercise any of his or her remaining
|
||||
Copyright and Related Rights in the Work or (ii) assert any associated
|
||||
claims and causes of action with respect to the Work, in either case
|
||||
contrary to Affirmer's express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
|
||||
Affirmer offers the Work as-is and makes no representations or warranties
|
||||
of any kind concerning the Work, express, implied, statutory or otherwise,
|
||||
including without limitation warranties of title, merchantability, fitness
|
||||
for a particular purpose, non infringement, or the absence of latent or
|
||||
other defects, accuracy, or the present or absence of errors, whether or not
|
||||
discoverable, all to the greatest extent permissible under applicable law.
|
||||
|
||||
Affirmer disclaims responsibility for clearing rights of other persons that
|
||||
may apply to the Work or any use thereof, including without limitation any
|
||||
person's Copyright and Related Rights in the Work. Further, Affirmer
|
||||
disclaims responsibility for obtaining any necessary consents, permissions
|
||||
or other rights required for any use of the Work.
|
||||
|
||||
Affirmer understands and acknowledges that Creative Commons is not a party
|
||||
to this document and has no duty or obligation with respect to this CC0 or
|
||||
use of the Work.
|
||||
|
||||
199
src/tools/web_api/dep/smtp-client/README.md
Normal file
199
src/tools/web_api/dep/smtp-client/README.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# smtp-client
|
||||
|
||||
This is an SMTP client library written in C which can get included
|
||||
directly into another program.
|
||||
|
||||
This library has been released into the public domain using
|
||||
[CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||
|
||||
Official repository location:
|
||||
[www.somnisoft.com/smtp-client](https://www.somnisoft.com/smtp-client)
|
||||
|
||||
## Feature list
|
||||
* C89
|
||||
* Cross-platform (POSIX, BSD, MacOS, Windows)
|
||||
* Send attachments
|
||||
* Send custom email headers
|
||||
* Specify multiple TO, CC, and BCC recipients
|
||||
* Simple API and simple error handling (see Examples section below)
|
||||
* Optional OpenSSL TLS connection and authentication methods
|
||||
* Test cases with 100% code and branch coverage
|
||||
* Doxygen with 100% documentation including the test code
|
||||
* Free software (permissive - CC0)
|
||||
|
||||
Supports the following connection methods:
|
||||
* No encryption
|
||||
* STARTTLS (requires OpenSSL)
|
||||
* TLS direct connection (requires OpenSSL)
|
||||
|
||||
Supports the following authentication methods:
|
||||
* none
|
||||
* PLAIN
|
||||
* LOGIN
|
||||
* CRAM-MD5 (requires OpenSSL)
|
||||
|
||||
To include the library into your application, simply copy the src/smtp.h and
|
||||
src/smtp.c files into your project directory. Then include the smtp.h header
|
||||
into your C file, compile smtp.c, and include the resulting object file into
|
||||
the build system.
|
||||
|
||||
## Examples
|
||||
The following example code demonstrates how to use the library.
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
#include "smtp.h"
|
||||
#define MAIL_SERVER "mail.example.com"
|
||||
#define MAIL_PORT "587"
|
||||
#define MAIL_CONNECTION_SECURITY SMTP_SECURITY_STARTTLS
|
||||
#define MAIL_FLAGS (SMTP_DEBUG | \
|
||||
SMTP_NO_CERT_VERIFY) /* Do not verify cert. */
|
||||
#define MAIL_CAFILE NULL
|
||||
#define MAIL_AUTH SMTP_AUTH_PLAIN
|
||||
#define MAIL_USER "mail@example.com"
|
||||
#define MAIL_PASS "password"
|
||||
#define MAIL_FROM "mail@example.com"
|
||||
#define MAIL_FROM_NAME "From Name"
|
||||
#define MAIL_SUBJECT "Subject Line"
|
||||
#define MAIL_BODY "Email Body"
|
||||
#define MAIL_TO "to@example.com"
|
||||
#define MAIL_TO_NAME "To Name"
|
||||
int main(void)
|
||||
{
|
||||
struct smtp *smtp;
|
||||
int rc;
|
||||
rc = smtp_open(MAIL_SERVER,
|
||||
MAIL_PORT,
|
||||
MAIL_CONNECTION_SECURITY,
|
||||
MAIL_FLAGS,
|
||||
MAIL_CAFILE,
|
||||
&smtp);
|
||||
rc = smtp_auth(smtp,
|
||||
MAIL_AUTH,
|
||||
MAIL_USER,
|
||||
MAIL_PASS);
|
||||
rc = smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_FROM,
|
||||
MAIL_FROM,
|
||||
MAIL_FROM_NAME);
|
||||
rc = smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_TO,
|
||||
MAIL_TO,
|
||||
MAIL_TO_NAME);
|
||||
rc = smtp_header_add(smtp,
|
||||
"Subject",
|
||||
MAIL_SUBJECT);
|
||||
rc = smtp_attachment_add_mem(smtp,
|
||||
"test.txt",
|
||||
"Test email attachment.",
|
||||
-1);
|
||||
rc = smtp_mail(smtp,
|
||||
MAIL_BODY);
|
||||
rc = smtp_close(smtp);
|
||||
if(rc != SMTP_STATUS_OK){
|
||||
fprintf(stderr, "smtp failed: %s\n", smtp_status_code_errstr(rc));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Place the code snippet above into a file named 'test.c' and change each #define
|
||||
to the appropriate values for your mail server. Then copy smtp.c and smtp.h
|
||||
into the same directory and run the following commands to compile with OpenSSL
|
||||
support.
|
||||
|
||||
cc -DSMTP_OPENSSL smtp.c -c -o smtp.o
|
||||
|
||||
cc -DSMTP_OPENSSL test.c -c -o test.o
|
||||
|
||||
cc test.o smtp.o -o smtp_test -lssl -lcrypto
|
||||
|
||||
If you do not need OpenSSL support, remove the -DSMTP_OPENSSL and the
|
||||
-lssl and -lcrypto arguments. The commands as above should create an
|
||||
executable called 'smtp_test' which can send a test email using the specified
|
||||
mail server.
|
||||
|
||||
A minimum amount of error checking has been included. Note that in the above
|
||||
example, the program checks for an error at the end of the mail session after
|
||||
calling smtp_close. We can do this because if an error occurs in any of the
|
||||
prior functions, the error will continue to propagate through any future
|
||||
function calls until either closing the SMTP context using smtp_close or by
|
||||
resetting the error condition using smtp_status_code_clear.
|
||||
|
||||
The following example demonstrates how to send an HTML email by overriding the
|
||||
Content-Type header. When overriding this header, any attachments added using
|
||||
the smtp_attachment_add\* functions will get ignored. The application must
|
||||
generate the appropriate MIME sections (if needed) when overriding this
|
||||
header.
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
#include "smtp.h"
|
||||
#define MAIL_SERVER "localhost"
|
||||
#define MAIL_PORT "25"
|
||||
#define MAIL_CONNECTION_SECURITY SMTP_SECURITY_NONE
|
||||
#define MAIL_FLAGS SMTP_DEBUG
|
||||
#define MAIL_CAFILE NULL
|
||||
#define MAIL_AUTH SMTP_AUTH_NONE
|
||||
#define MAIL_USER "mail@somnisoft.com"
|
||||
#define MAIL_PASS "password"
|
||||
#define MAIL_FROM "mail@somnisoft.com"
|
||||
#define MAIL_FROM_NAME "From Name"
|
||||
#define MAIL_SUBJECT "Subject Line"
|
||||
#define MAIL_TO "mail@somnisoft.com"
|
||||
#define MAIL_TO_NAME "To Name"
|
||||
int main(void){
|
||||
struct smtp *smtp;
|
||||
enum smtp_status_code rc;
|
||||
const char *const email_body =
|
||||
"<html>\n"
|
||||
" <head><title>HTML Email</title></head>\n"
|
||||
" <body>\n"
|
||||
" <h1>H1</h1>\n"
|
||||
" <h2>H2</h1>\n"
|
||||
" <h3>H3</h1>\n"
|
||||
" <h4>H4</h1>\n"
|
||||
" <h5>H5</h1>\n"
|
||||
" <h6>H6</h1>\n"
|
||||
" </body>\n"
|
||||
"</html>\n";
|
||||
smtp_open(MAIL_SERVER,
|
||||
MAIL_PORT,
|
||||
MAIL_CONNECTION_SECURITY,
|
||||
MAIL_FLAGS,
|
||||
MAIL_CAFILE,
|
||||
&smtp);
|
||||
smtp_auth(smtp,
|
||||
MAIL_AUTH,
|
||||
MAIL_USER,
|
||||
MAIL_PASS);
|
||||
smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_FROM,
|
||||
MAIL_FROM,
|
||||
MAIL_FROM_NAME);
|
||||
smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_TO,
|
||||
MAIL_TO,
|
||||
MAIL_TO_NAME);
|
||||
smtp_header_add(smtp,
|
||||
"Subject",
|
||||
MAIL_SUBJECT);
|
||||
smtp_header_add(smtp,
|
||||
"Content-Type",
|
||||
"text/html");
|
||||
smtp_mail(smtp, email_body);
|
||||
rc = smtp_close(smtp);
|
||||
if(rc != SMTP_STATUS_OK){
|
||||
fprintf(stderr, "smtp failed: %s\n", smtp_status_code_errstr(rc));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Technical Documentation
|
||||
See the [Technical Documentation](
|
||||
https://www.somnisoft.com/smtp-client/technical-documentation/index.html)
|
||||
generated from Doxygen.
|
||||
|
||||
117
src/tools/web_api/dep/smtp-client/src/SMTPMail.cpp
Normal file
117
src/tools/web_api/dep/smtp-client/src/SMTPMail.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief SMTPMail class wrapper for smtp-client library.
|
||||
* @author James Humphrey (mail@somnisoft.com)
|
||||
* @version 1.00
|
||||
*
|
||||
* Thin CPP wrapper class around the smtp-client C library.
|
||||
*
|
||||
* This software has been placed into the public domain using CC0.
|
||||
*/
|
||||
#include "SMTPMail.h"
|
||||
|
||||
SMTPMailException::SMTPMailException(enum smtp_status_code status_code){
|
||||
this->status_code = status_code;
|
||||
}
|
||||
|
||||
const char*
|
||||
SMTPMailException::what() const noexcept {
|
||||
return smtp_status_code_errstr(this->status_code);
|
||||
}
|
||||
|
||||
SMTPMail::SMTPMail(void){
|
||||
}
|
||||
|
||||
SMTPMail::~SMTPMail(void){
|
||||
}
|
||||
|
||||
void SMTPMail::open(const char *const server,
|
||||
const char *const port,
|
||||
enum smtp_connection_security connection_security,
|
||||
enum smtp_flag flags,
|
||||
const char *const cafile){
|
||||
this->rc = smtp_open(server,
|
||||
port,
|
||||
connection_security,
|
||||
flags,
|
||||
cafile,
|
||||
&this->smtp);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
void SMTPMail::auth(enum smtp_authentication_method auth_method,
|
||||
const char *const user,
|
||||
const char *const pass){
|
||||
this->rc = smtp_auth(this->smtp, auth_method, user, pass);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
void SMTPMail::mail(const char *const body){
|
||||
this->rc = smtp_mail(this->smtp, body);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
void SMTPMail::close(void){
|
||||
this->rc = smtp_close(this->smtp);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
int SMTPMail::status_code_get(void){
|
||||
return smtp_status_code_get(this->smtp);
|
||||
}
|
||||
|
||||
void SMTPMail::status_code_set(enum smtp_status_code new_status_code){
|
||||
this->rc = smtp_status_code_set(this->smtp, new_status_code);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
void SMTPMail::header_add(const char *const key,
|
||||
const char *const value){
|
||||
this->rc = smtp_header_add(this->smtp, key, value);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
void SMTPMail::header_clear_all(void){
|
||||
smtp_header_clear_all(this->smtp);
|
||||
}
|
||||
|
||||
void SMTPMail::address_add(enum smtp_address_type type,
|
||||
const char *const email,
|
||||
const char *const name){
|
||||
this->rc = smtp_address_add(this->smtp, type, email, name);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
void SMTPMail::address_clear_all(void){
|
||||
smtp_address_clear_all(this->smtp);
|
||||
}
|
||||
|
||||
void SMTPMail::attachment_add_path(const char *const name,
|
||||
const char *const path){
|
||||
this->rc = smtp_attachment_add_path(this->smtp, name, path);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
void SMTPMail::attachment_add_fp(const char *const name,
|
||||
FILE *fp){
|
||||
this->rc = smtp_attachment_add_fp(this->smtp, name, fp);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
void SMTPMail::attachment_add_mem(const char *const name,
|
||||
const void *const data,
|
||||
size_t datasz){
|
||||
this->rc = smtp_attachment_add_mem(this->smtp, name, data, datasz);
|
||||
this->throw_bad_status_code();
|
||||
}
|
||||
|
||||
void SMTPMail::attachment_clear_all(void){
|
||||
smtp_attachment_clear_all(this->smtp);
|
||||
}
|
||||
|
||||
void SMTPMail::throw_bad_status_code(void){
|
||||
if(this->rc != SMTP_STATUS_OK){
|
||||
throw SMTPMailException(this->rc);
|
||||
}
|
||||
}
|
||||
|
||||
243
src/tools/web_api/dep/smtp-client/src/SMTPMail.h
Normal file
243
src/tools/web_api/dep/smtp-client/src/SMTPMail.h
Normal file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief SMTPMail class wrapper for smtp-client library.
|
||||
* @author James Humphrey (mail@somnisoft.com)
|
||||
* @version 1.00
|
||||
*
|
||||
* Thin CPP wrapper class around the smtp-client C library.
|
||||
*
|
||||
* This software has been placed into the public domain using CC0.
|
||||
*/
|
||||
#ifndef SMTP_MAIL_H
|
||||
#define SMTP_MAIL_H
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include "smtp.h"
|
||||
|
||||
/**
|
||||
* @class SMTPMailException
|
||||
*
|
||||
* This exception will get thrown whenever an SMTP client function fails.
|
||||
*/
|
||||
class SMTPMailException : public std::exception{
|
||||
public:
|
||||
/**
|
||||
* Create the exception with the corresponding @p status_code.
|
||||
*
|
||||
* @param[in] status_code An error status code returned from a previous call
|
||||
* to an smtp-client library function.
|
||||
*/
|
||||
SMTPMailException(enum smtp_status_code status_code);
|
||||
|
||||
/**
|
||||
* Get a description of the smtp-client status code that caused
|
||||
* this exception.
|
||||
*
|
||||
* @return Null-terminated string describing the smtp-client status code.
|
||||
*/
|
||||
virtual const char* what() const noexcept;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The status code generated by any of the smtp-client library functions.
|
||||
*/
|
||||
enum smtp_status_code status_code;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class SMTPMail
|
||||
*
|
||||
* Thin CPP wrapper class over the smtp-client C library.
|
||||
*/
|
||||
class SMTPMail{
|
||||
public:
|
||||
/**
|
||||
* Create the @ref SMTPMail object.
|
||||
*/
|
||||
SMTPMail(void);
|
||||
|
||||
/**
|
||||
* Free the @ref SMTPMail object.
|
||||
*/
|
||||
~SMTPMail(void);
|
||||
|
||||
/**
|
||||
* Open a connection to an SMTP server.
|
||||
*
|
||||
* See @ref smtp_open.
|
||||
*
|
||||
* @param[in] server Server name or IP address.
|
||||
* @param[in] port Server port number.
|
||||
* @param[in] connection_security See @ref smtp_connection_security.
|
||||
* @param[in] flags See @ref smtp_flag.
|
||||
* @param[in] cafile Path to certificate file, or NULL to use
|
||||
* certificates in the default path.
|
||||
*/
|
||||
void open(const char *const server,
|
||||
const char *const port,
|
||||
enum smtp_connection_security connection_security,
|
||||
enum smtp_flag flags,
|
||||
const char *const cafile);
|
||||
|
||||
/**
|
||||
* Authenticate the user using one of the methods listed in
|
||||
* @ref smtp_authentication_method.
|
||||
*
|
||||
* See @ref smtp_auth.
|
||||
*
|
||||
* @param[in] auth_method See @ref smtp_authentication_method.
|
||||
* @param[in] user Server authentication user name.
|
||||
* @param[in] pass Server authentication user password.
|
||||
*/
|
||||
void auth(enum smtp_authentication_method auth_method,
|
||||
const char *const user,
|
||||
const char *const pass);
|
||||
|
||||
/**
|
||||
* Sends an email using the addresses, attachments, and headers defined
|
||||
* in the current SMTP context.
|
||||
*
|
||||
* See @ref smtp_mail.
|
||||
*
|
||||
* @param[in] body Null-terminated string to send in the email body.
|
||||
*/
|
||||
void mail(const char *const body);
|
||||
|
||||
/**
|
||||
* Close the SMTP connection and frees all resources held by the
|
||||
* SMTP context.
|
||||
*
|
||||
* See @ref smtp_close.
|
||||
*/
|
||||
void close(void);
|
||||
|
||||
/**
|
||||
* Get the current status/error code described in @ref smtp_status_code.
|
||||
*
|
||||
* See @ref smtp_status_code_get.
|
||||
*
|
||||
* @return @ref smtp_status_code.
|
||||
*/
|
||||
int status_code_get(void);
|
||||
|
||||
/**
|
||||
* Set the error status of the SMTP client context.
|
||||
*
|
||||
* See @ref smtp_status_code_set.
|
||||
*
|
||||
* @param[in] new_status_code See @ref smtp_status_code.
|
||||
*/
|
||||
void status_code_set(enum smtp_status_code new_status_code);
|
||||
|
||||
/**
|
||||
* Add a key/value header to the header list in the SMTP context.
|
||||
*
|
||||
* See @ref smtp_header_add.
|
||||
*
|
||||
* @param[in] key Key name for new header. It must consist only of
|
||||
* printable US-ASCII characters except colon.
|
||||
* @param[in] value Value for new header. It must consist only of printable
|
||||
* US-ASCII, space, or horizontal tab. If set to NULL,
|
||||
* this will prevent the header from printing out.
|
||||
*/
|
||||
void header_add(const char *const key,
|
||||
const char *const value);
|
||||
|
||||
/**
|
||||
* Free all memory related to email headers.
|
||||
*
|
||||
* See @ref smtp_header_clear_all.
|
||||
*/
|
||||
void header_clear_all(void);
|
||||
|
||||
/**
|
||||
* Add a FROM, TO, CC, or BCC address destination to this SMTP context.
|
||||
*
|
||||
* See @ref smtp_address_add.
|
||||
*
|
||||
* @param[in] type See @ref smtp_address_type.
|
||||
* @param[in] email The email address of the party. Must consist only of
|
||||
* printable characters excluding the angle brackets
|
||||
* (<) and (>).
|
||||
* @param[in] name Name or description of the party. Must consist only of
|
||||
* printable characters, excluding the quote characters. If
|
||||
* set to NULL, no name will get associated with this email.
|
||||
*/
|
||||
void address_add(enum smtp_address_type type,
|
||||
const char *const email,
|
||||
const char *const name);
|
||||
|
||||
/**
|
||||
* Free all memory related to the address list.
|
||||
*
|
||||
* See @ref smtp_address_clear_all.
|
||||
*/
|
||||
void address_clear_all(void);
|
||||
|
||||
/**
|
||||
* Add a file attachment from a path.
|
||||
*
|
||||
* See @ref smtp_attachment_add_mem.
|
||||
*
|
||||
* @param[in] name Filename of the attachment shown to recipients.
|
||||
* @param[in] path Path of file location to read from.
|
||||
*/
|
||||
void attachment_add_path(const char *const name,
|
||||
const char *const path);
|
||||
|
||||
/**
|
||||
* Add an attachment using a file pointer.
|
||||
*
|
||||
* See @ref smtp_attachment_add_fp.
|
||||
*
|
||||
* @param[in] name Filename of the attachment shown to recipients.
|
||||
* @param[in] fp File pointer already opened by the caller.
|
||||
*/
|
||||
void attachment_add_fp(const char *const name,
|
||||
FILE *fp);
|
||||
|
||||
/**
|
||||
* Add an attachment with the data pulled from memory.
|
||||
*
|
||||
* See @ref smtp_attachment_add_mem.
|
||||
*
|
||||
* @param[in] name Filename of the attachment shown to recipients. Must
|
||||
* consist only of printable characters excluding the
|
||||
* quote characters (') and ("), or the space character
|
||||
* ( ).
|
||||
* @param[in] data Raw attachment data stored in memory.
|
||||
* @param[in] datasz Number of bytes in @p data, or -1 if data
|
||||
* null-terminated.
|
||||
*/
|
||||
void attachment_add_mem(const char *const name,
|
||||
const void *const data,
|
||||
size_t datasz);
|
||||
|
||||
/**
|
||||
* Remove all attachments from the SMTP client context.
|
||||
*
|
||||
* See @ref smtp_attachment_clear_all.
|
||||
*/
|
||||
void attachment_clear_all(void);
|
||||
|
||||
private:
|
||||
/**
|
||||
* SMTP client context.
|
||||
*/
|
||||
struct smtp *smtp;
|
||||
|
||||
/**
|
||||
* Store the last smtp-client library function return code.
|
||||
*/
|
||||
enum smtp_status_code rc;
|
||||
|
||||
/**
|
||||
* Throw @ref SMTPMailException if the last smtp-client library function
|
||||
* failed.
|
||||
*/
|
||||
void throw_bad_status_code(void);
|
||||
};
|
||||
|
||||
#endif /* SMTP_MAIL_H */
|
||||
|
||||
558
src/tools/web_api/dep/smtp-client/src/mailx.c
Normal file
558
src/tools/web_api/dep/smtp-client/src/mailx.c
Normal file
@@ -0,0 +1,558 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief POSIX mailx utility.
|
||||
* @author James Humphrey (mail@somnisoft.com)
|
||||
* @version 1.00
|
||||
*
|
||||
* Implementation of POSIX mailx utility in send mode.
|
||||
*
|
||||
* mailx [-s subject] [[-S option]...] [[-a attachment]...] address...
|
||||
*
|
||||
* This software has been placed into the public domain using CC0.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Required on some POSIX systems to include some standard functions.
|
||||
*/
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "smtp.h"
|
||||
|
||||
/**
|
||||
* Stores the to and from email addresses.
|
||||
*/
|
||||
struct mailx_address{
|
||||
/**
|
||||
* See @ref smtp_address_type.
|
||||
*/
|
||||
enum smtp_address_type address_type;
|
||||
|
||||
/**
|
||||
* Email address.
|
||||
*/
|
||||
char email[1000];
|
||||
};
|
||||
|
||||
/**
|
||||
* The attachment name and path stored for each attachment to send to the
|
||||
* recipient.
|
||||
*/
|
||||
struct mailx_attachment{
|
||||
/**
|
||||
* File name for this attachment to display to the recipient.
|
||||
*/
|
||||
char name[1000];
|
||||
|
||||
/**
|
||||
* Local file path pointing to the attachment to send.
|
||||
*/
|
||||
char path[1000];
|
||||
};
|
||||
|
||||
/**
|
||||
* The mailx context structure containing the parameters for setting up the
|
||||
* SMTP connection and sending the email.
|
||||
*/
|
||||
struct mailx{
|
||||
/**
|
||||
* SMTP client context.
|
||||
*/
|
||||
struct smtp *smtp;
|
||||
|
||||
/**
|
||||
* Email subject line.
|
||||
*/
|
||||
const char *subject;
|
||||
|
||||
/**
|
||||
* Email body text.
|
||||
*/
|
||||
char *body;
|
||||
|
||||
/**
|
||||
* SMTP server name or IP address.
|
||||
*/
|
||||
char *server;
|
||||
|
||||
/**
|
||||
* SMTP server port number.
|
||||
*/
|
||||
char *port;
|
||||
|
||||
/**
|
||||
* SMTP account user name used for authenticating.
|
||||
*/
|
||||
char *user;
|
||||
|
||||
/**
|
||||
* SMTP account password used for authenticating.
|
||||
*/
|
||||
char *pass;
|
||||
|
||||
/**
|
||||
* From email address or name.
|
||||
*/
|
||||
char *from;
|
||||
|
||||
/**
|
||||
* Determine if using a TLS encrypted connection or plain socket.
|
||||
*/
|
||||
enum smtp_connection_security connection_security;
|
||||
|
||||
/**
|
||||
* SMTP user account authentication method.
|
||||
*/
|
||||
enum smtp_authentication_method auth_method;
|
||||
|
||||
/**
|
||||
* Miscellaneous control flags for smtp-lib.
|
||||
*
|
||||
* See @ref smtp_flag for more details.
|
||||
*/
|
||||
enum smtp_flag smtp_flags;
|
||||
|
||||
/**
|
||||
* List of email addresses to send to.
|
||||
*/
|
||||
struct mailx_address *address_list;
|
||||
|
||||
/**
|
||||
* Number of email addresses in @ref address_list.
|
||||
*/
|
||||
size_t num_address;
|
||||
|
||||
/**
|
||||
* List of files to attach in the email.
|
||||
*/
|
||||
struct mailx_attachment *attachment_list;
|
||||
|
||||
/**
|
||||
* Number of attachments in @ref attachment_list.
|
||||
*/
|
||||
size_t num_attachment;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read the entire contents of a file stream and store the data into a
|
||||
* dynamically allocated buffer.
|
||||
*
|
||||
* @param[in] stream File stream already opened by the caller.
|
||||
* @param[out] bytes_read Number of bytes stored in the return buffer.
|
||||
* @retval char* A dynamically allocated buffer which contains the entire
|
||||
* contents of @p stream. The caller must free this memory
|
||||
* when done.
|
||||
* @retval NULL Memory allocation or file read error.
|
||||
*/
|
||||
static char *
|
||||
smtp_ffile_get_contents(FILE *stream,
|
||||
size_t *bytes_read){
|
||||
char *read_buf;
|
||||
size_t bufsz;
|
||||
char *new_buf;
|
||||
const size_t BUFSZ_INCREMENT = 512;
|
||||
|
||||
read_buf = NULL;
|
||||
bufsz = 0;
|
||||
|
||||
if(bytes_read){
|
||||
*bytes_read = 0;
|
||||
}
|
||||
|
||||
do{
|
||||
size_t bytes_read_loop;
|
||||
if((new_buf = realloc(read_buf, bufsz + BUFSZ_INCREMENT)) == NULL){
|
||||
free(read_buf);
|
||||
return NULL;
|
||||
}
|
||||
read_buf = new_buf;
|
||||
bufsz += BUFSZ_INCREMENT;
|
||||
|
||||
bytes_read_loop = fread(&read_buf[bufsz - BUFSZ_INCREMENT],
|
||||
sizeof(char),
|
||||
BUFSZ_INCREMENT,
|
||||
stream);
|
||||
if(bytes_read){
|
||||
*bytes_read += bytes_read_loop;
|
||||
}
|
||||
if(ferror(stream)){
|
||||
free(read_buf);
|
||||
return NULL;
|
||||
}
|
||||
} while(!feof(stream));
|
||||
|
||||
return read_buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append this email to the list of email addresses to send to.
|
||||
*
|
||||
* @param[in] mailx Append the email address into this mailx context.
|
||||
* @param[in] address_type See @ref smtp_address_type.
|
||||
* @param[in] email Email address to send to.
|
||||
*/
|
||||
static void
|
||||
mailx_address_append(struct mailx *const mailx,
|
||||
enum smtp_address_type address_type,
|
||||
const char *const email){
|
||||
struct mailx_address *new_address;
|
||||
size_t new_address_list_sz;
|
||||
|
||||
mailx->num_address += 1;
|
||||
new_address_list_sz = mailx->num_address * sizeof(*mailx->address_list);
|
||||
if((mailx->address_list = realloc(mailx->address_list,
|
||||
new_address_list_sz)) == NULL){
|
||||
err(1, "realloc");
|
||||
}
|
||||
|
||||
new_address = &mailx->address_list[mailx->num_address - 1];
|
||||
new_address->address_type = address_type;
|
||||
strncpy(new_address->email, email, sizeof(new_address->email));
|
||||
new_address->email[sizeof(new_address->email) - 1] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the email using the configuration options in the @p mailx context.
|
||||
*
|
||||
* @param[in] mailx Email context.
|
||||
*/
|
||||
static void
|
||||
mailx_send(struct mailx *const mailx){
|
||||
int rc;
|
||||
size_t i;
|
||||
const struct mailx_address *address;
|
||||
const struct mailx_attachment *attachment;
|
||||
|
||||
smtp_open(mailx->server,
|
||||
mailx->port,
|
||||
mailx->connection_security,
|
||||
mailx->smtp_flags,
|
||||
NULL,
|
||||
&mailx->smtp);
|
||||
|
||||
smtp_auth(mailx->smtp,
|
||||
mailx->auth_method,
|
||||
mailx->user,
|
||||
mailx->pass);
|
||||
|
||||
for(i = 0; i < mailx->num_address; i++){
|
||||
address = &mailx->address_list[i];
|
||||
smtp_address_add(mailx->smtp, address->address_type, address->email, NULL);
|
||||
}
|
||||
|
||||
for(i = 0; i < mailx->num_attachment; i++){
|
||||
attachment = &mailx->attachment_list[i];
|
||||
smtp_attachment_add_path(mailx->smtp, attachment->name, attachment->path);
|
||||
}
|
||||
smtp_header_add(mailx->smtp, "Subject", mailx->subject);
|
||||
smtp_mail(mailx->smtp, mailx->body);
|
||||
|
||||
rc = smtp_close(mailx->smtp);
|
||||
|
||||
if(rc != SMTP_STATUS_OK){
|
||||
errx(1, "%s", smtp_status_code_errstr(rc));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a file to the @p mailx context.
|
||||
*
|
||||
* @param[in] mailx Store the attachment details into this mailx context.
|
||||
* @param[in] filename File name to display to the recipient.
|
||||
* @param[in] path Local path of file to attach.
|
||||
*/
|
||||
static void
|
||||
mailx_append_attachment(struct mailx *const mailx,
|
||||
const char *const filename,
|
||||
const char *const path){
|
||||
struct mailx_attachment *new_attachment;
|
||||
size_t new_attachment_list_sz;
|
||||
|
||||
if(filename == NULL || path == NULL){
|
||||
errx(1, "must provide attachment with valid name:path");
|
||||
}
|
||||
|
||||
new_attachment_list_sz = (mailx->num_attachment + 1) *
|
||||
sizeof(*mailx->attachment_list);
|
||||
if((mailx->attachment_list = realloc(mailx->attachment_list,
|
||||
new_attachment_list_sz)) == NULL){
|
||||
err(1, "realloc: attachment list");
|
||||
}
|
||||
new_attachment = &mailx->attachment_list[mailx->num_attachment];
|
||||
mailx->num_attachment += 1;
|
||||
|
||||
strncpy(new_attachment->name, filename, sizeof(new_attachment->name));
|
||||
new_attachment->name[sizeof(new_attachment->name) - 1] = '\0';
|
||||
|
||||
strncpy(new_attachment->path, path, sizeof(new_attachment->path));
|
||||
new_attachment->path[sizeof(new_attachment->path) - 1] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the file name and path and attach it to the @p mailx context.
|
||||
*
|
||||
* @param[in] mailx Store the attachment details into this mailx context.
|
||||
* @param[in] attach_arg String with format: 'filename:filepath'.
|
||||
*/
|
||||
static void
|
||||
mailx_append_attachment_arg(struct mailx *const mailx,
|
||||
const char *const attach_arg){
|
||||
char *attach_arg_dup;
|
||||
char *filename;
|
||||
char *filepath;
|
||||
|
||||
if((attach_arg_dup = strdup(attach_arg)) == NULL){
|
||||
err(1, "strdup: %s", attach_arg);
|
||||
}
|
||||
|
||||
filename = strtok(attach_arg_dup, ":");
|
||||
filepath = strtok(NULL, ":");
|
||||
|
||||
mailx_append_attachment(mailx, filename, filepath);
|
||||
|
||||
free(attach_arg_dup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the -S option which contains a key/value pair separated by an '='
|
||||
* character.
|
||||
*
|
||||
* @param[in] mailx Store the results of the option parsing into the relevant
|
||||
* field in this mailx context.
|
||||
* @param[in] option String containing key/value option to parse.
|
||||
*/
|
||||
static void
|
||||
mailx_parse_smtp_option(struct mailx *const mailx,
|
||||
const char *const option){
|
||||
char *optdup;
|
||||
char *opt_key;
|
||||
char *opt_value;
|
||||
int rc;
|
||||
|
||||
rc = 0;
|
||||
|
||||
if((optdup = strdup(option)) == NULL){
|
||||
err(1, "strdup: option: %s", option);
|
||||
}
|
||||
|
||||
if((opt_key = strtok(optdup, "=")) == NULL){
|
||||
errx(1, "strtok: %s", optdup);
|
||||
}
|
||||
|
||||
opt_value = strtok(NULL, "=");
|
||||
|
||||
if(strcmp(opt_key, "smtp-security") == 0){
|
||||
if(strcmp(opt_value, "none") == 0){
|
||||
mailx->connection_security = SMTP_SECURITY_NONE;
|
||||
}
|
||||
#ifdef SMTP_OPENSSL
|
||||
else if(strcmp(opt_value, "tls") == 0){
|
||||
mailx->connection_security = SMTP_SECURITY_TLS;
|
||||
}
|
||||
else if(strcmp(opt_value, "starttls") == 0){
|
||||
mailx->connection_security = SMTP_SECURITY_STARTTLS;
|
||||
}
|
||||
#endif /* SMTP_OPENSSL */
|
||||
else{
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
else if(strcmp(opt_key, "smtp-auth") == 0){
|
||||
if(strcmp(opt_value, "none") == 0){
|
||||
mailx->auth_method = SMTP_AUTH_NONE;
|
||||
}
|
||||
else if(strcmp(opt_value, "plain") == 0){
|
||||
mailx->auth_method = SMTP_AUTH_PLAIN;
|
||||
}
|
||||
else if(strcmp(opt_value, "login") == 0){
|
||||
mailx->auth_method = SMTP_AUTH_LOGIN;
|
||||
}
|
||||
#ifdef SMTP_OPENSSL
|
||||
else if(strcmp(opt_value, "cram-md5") == 0){
|
||||
mailx->auth_method = SMTP_AUTH_CRAM_MD5;
|
||||
}
|
||||
#endif /* SMTP_OPENSSL */
|
||||
else{
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
else if(strcmp(opt_key, "smtp-flag") == 0){
|
||||
if(strcmp(opt_value, "debug") == 0){
|
||||
mailx->smtp_flags |= SMTP_DEBUG;
|
||||
}
|
||||
else if(strcmp(opt_value, "no-cert-verify") == 0){
|
||||
mailx->smtp_flags |= SMTP_NO_CERT_VERIFY;
|
||||
}
|
||||
else{
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
else if(strcmp(opt_key, "smtp-server") == 0){
|
||||
if((mailx->server = strdup(opt_value)) == NULL){
|
||||
err(1, "strdup");
|
||||
}
|
||||
}
|
||||
else if(strcmp(opt_key, "smtp-port") == 0){
|
||||
if((mailx->port = strdup(opt_value)) == NULL){
|
||||
err(1, "strdup");
|
||||
}
|
||||
}
|
||||
else if(strcmp(opt_key, "smtp-user") == 0){
|
||||
if((mailx->user = strdup(opt_value)) == NULL){
|
||||
err(1, "strdup");
|
||||
}
|
||||
}
|
||||
else if(strcmp(opt_key, "smtp-pass") == 0){
|
||||
if((mailx->pass = strdup(opt_value)) == NULL){
|
||||
err(1, "strdup");
|
||||
}
|
||||
}
|
||||
else if(strcmp(opt_key, "smtp-from") == 0){
|
||||
if((mailx->from = strdup(opt_value)) == NULL){
|
||||
err(1, "strdup");
|
||||
}
|
||||
}
|
||||
else{
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
free(optdup);
|
||||
|
||||
if(rc < 0){
|
||||
errx(1, "invalid argument: %s", option);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and set the default options in the mailx context.
|
||||
*
|
||||
* See description of -S argument in main for more details.
|
||||
*
|
||||
* @param[in] mailx The mailx content to initialize.
|
||||
*/
|
||||
static void
|
||||
mailx_init_default_values(struct mailx *const mailx){
|
||||
memset(mailx, 0, sizeof(*mailx));
|
||||
mailx->subject = "";
|
||||
mailx->connection_security = SMTP_SECURITY_NONE;
|
||||
mailx->auth_method = SMTP_AUTH_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the allocated memory associated with the mailx context.
|
||||
*
|
||||
* @param[in] mailx The mailx context to free.
|
||||
*/
|
||||
static void
|
||||
mailx_free(const struct mailx *const mailx){
|
||||
free(mailx->body);
|
||||
free(mailx->server);
|
||||
free(mailx->port);
|
||||
free(mailx->user);
|
||||
free(mailx->pass);
|
||||
free(mailx->from);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main program entry point for the mailx utility.
|
||||
*
|
||||
* This program supports the following options:
|
||||
* - -a 'name:path' - Attach a file with name to display to recipient and
|
||||
* file path pointing to file location on local storage.
|
||||
* - -s subject - Email subject line.
|
||||
* - -S key=value - A key/value pair to set various configuration options,
|
||||
* controlling the behavior of the SMTP client connection.
|
||||
*
|
||||
* The following list contains possible options for the -S argument:
|
||||
* - smtp-security - none, tls, starttls
|
||||
* - smtp-auth - none, plain, login, cram-md5
|
||||
* - smtp-flag - debug, no-cert-verify
|
||||
* - smtp-server - server name or IP address
|
||||
* - smtp-port - server port number
|
||||
* - smtp-user - server authentication user name
|
||||
* - smtp-pass - server authentication user password
|
||||
* - smtp-from - from email account
|
||||
*
|
||||
* The following list shows the default option for -S argument if not provided:
|
||||
* - smtp-security - none
|
||||
* - smtp-auth - none
|
||||
* - smtp-flag - none
|
||||
* - smtp-server - localhost
|
||||
* - smtp-port - 25
|
||||
* - smtp-user - none
|
||||
* - smtp-pass - none
|
||||
* - smtp-from - none
|
||||
*
|
||||
* @param[in] argc Number of arguments in @p argv.
|
||||
* @param[in] argv String array containing the program name and any optional
|
||||
* parameters described above.
|
||||
* @retval 0 Email has been sent.
|
||||
* @retval 1 An error occurred while sending email. Although unlikely, an email
|
||||
* can still get sent even after returning with this error code.
|
||||
*/
|
||||
int main(int argc, char *argv[]){
|
||||
int rc;
|
||||
int i;
|
||||
struct mailx mailx;
|
||||
|
||||
mailx_init_default_values(&mailx);
|
||||
|
||||
while((rc = getopt(argc, argv, "a:s:S:")) != -1){
|
||||
switch(rc){
|
||||
case 'a':
|
||||
mailx_append_attachment_arg(&mailx, optarg);
|
||||
break;
|
||||
case 's':
|
||||
mailx.subject = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
mailx_parse_smtp_option(&mailx, optarg);
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if(argc < 1){
|
||||
errx(1, "must provide at least one email destination address");
|
||||
}
|
||||
|
||||
if(mailx.from == NULL){
|
||||
errx(1, "must provide a FROM address");
|
||||
}
|
||||
|
||||
if(mailx.server == NULL){
|
||||
if((mailx.server = strdup("localhost")) == NULL){
|
||||
err(1, "strdup");
|
||||
}
|
||||
}
|
||||
|
||||
if(mailx.port == NULL){
|
||||
if((mailx.port = strdup("25")) == NULL){
|
||||
err(1, "strdup");
|
||||
}
|
||||
}
|
||||
|
||||
puts("Reading email body from stdin");
|
||||
if((mailx.body = smtp_ffile_get_contents(stdin, NULL)) == NULL){
|
||||
err(1, "failed to read email body from stdin");
|
||||
}
|
||||
|
||||
mailx_address_append(&mailx, SMTP_ADDRESS_FROM, mailx.from);
|
||||
|
||||
for(i = 0; i < argc; i++){
|
||||
mailx_address_append(&mailx, SMTP_ADDRESS_TO, argv[i]);
|
||||
}
|
||||
|
||||
mailx_send(&mailx);
|
||||
mailx_free(&mailx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
3528
src/tools/web_api/dep/smtp-client/src/smtp.c
Normal file
3528
src/tools/web_api/dep/smtp-client/src/smtp.c
Normal file
File diff suppressed because it is too large
Load Diff
635
src/tools/web_api/dep/smtp-client/src/smtp.h
Normal file
635
src/tools/web_api/dep/smtp-client/src/smtp.h
Normal file
@@ -0,0 +1,635 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief SMTP client library.
|
||||
* @author James Humphrey (mail@somnisoft.com)
|
||||
* @version 1.00
|
||||
*
|
||||
* This SMTP client library allows the user to send emails to an SMTP server.
|
||||
* The user can include custom headers and MIME attachments.
|
||||
*
|
||||
* This software has been placed into the public domain using CC0.
|
||||
*/
|
||||
#ifndef SMTP_H
|
||||
#define SMTP_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
/**
|
||||
* Maximum value of size_t type.
|
||||
*/
|
||||
# define SIZE_MAX ((size_t)(-1))
|
||||
#endif /* SIZE_MAX */
|
||||
|
||||
/**
|
||||
* Status codes indicating success or failure from calling any of the
|
||||
* SMTP library functions.
|
||||
*
|
||||
* This code gets returned by all functions in this header.
|
||||
*/
|
||||
enum smtp_status_code{
|
||||
/**
|
||||
* Successful operation completed.
|
||||
*/
|
||||
SMTP_STATUS_OK = 0,
|
||||
|
||||
/**
|
||||
* Memory allocation failed.
|
||||
*/
|
||||
SMTP_STATUS_NOMEM = 1,
|
||||
|
||||
/**
|
||||
* Failed to connect to the mail server.
|
||||
*/
|
||||
SMTP_STATUS_CONNECT = 2,
|
||||
|
||||
/**
|
||||
* Failed to handshake or negotiate a TLS connection with the server.
|
||||
*/
|
||||
SMTP_STATUS_HANDSHAKE = 3,
|
||||
|
||||
/**
|
||||
* Failed to authenticate with the given credentials.
|
||||
*/
|
||||
SMTP_STATUS_AUTH = 4,
|
||||
|
||||
/**
|
||||
* Failed to send bytes to the server.
|
||||
*/
|
||||
SMTP_STATUS_SEND = 5,
|
||||
|
||||
/**
|
||||
* Failed to receive bytes from the server.
|
||||
*/
|
||||
SMTP_STATUS_RECV = 6,
|
||||
|
||||
/**
|
||||
* Failed to properly close a connection.
|
||||
*/
|
||||
SMTP_STATUS_CLOSE = 7,
|
||||
|
||||
/**
|
||||
* SMTP server sent back an unexpected status code.
|
||||
*/
|
||||
SMTP_STATUS_SERVER_RESPONSE = 8,
|
||||
|
||||
/**
|
||||
* Invalid parameter.
|
||||
*/
|
||||
SMTP_STATUS_PARAM = 9,
|
||||
|
||||
/**
|
||||
* Failed to open or read a local file.
|
||||
*/
|
||||
SMTP_STATUS_FILE = 10,
|
||||
|
||||
/**
|
||||
* Failed to get the local date and time.
|
||||
*/
|
||||
SMTP_STATUS_DATE = 11,
|
||||
|
||||
/**
|
||||
* Indicates the last status code in the enumeration, useful for
|
||||
* bounds checking.
|
||||
*
|
||||
* Not a valid status code.
|
||||
*/
|
||||
SMTP_STATUS__LAST
|
||||
};
|
||||
|
||||
/**
|
||||
* Address source and destination types.
|
||||
*/
|
||||
enum smtp_address_type{
|
||||
/**
|
||||
* From address.
|
||||
*/
|
||||
SMTP_ADDRESS_FROM = 0,
|
||||
|
||||
/**
|
||||
* To address.
|
||||
*/
|
||||
SMTP_ADDRESS_TO = 1,
|
||||
|
||||
/**
|
||||
* Copy address.
|
||||
*/
|
||||
SMTP_ADDRESS_CC = 2,
|
||||
|
||||
/**
|
||||
* Blind copy address.
|
||||
*
|
||||
* Recipients should not see any of the BCC addresses when they receive
|
||||
* their email. However, some SMTP server implementations may copy this
|
||||
* information into the mail header, so do not assume that this will
|
||||
* always get hidden. If the BCC addresses must not get shown to the
|
||||
* receivers, then send one separate email to each BCC party and add
|
||||
* the TO and CC addresses manually as a header property using
|
||||
* @ref smtp_header_add instead of as an address using
|
||||
* @ref smtp_address_add.
|
||||
*/
|
||||
SMTP_ADDRESS_BCC = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* Connect to the SMTP server using either an unencrypted socket or
|
||||
* TLS encryption.
|
||||
*/
|
||||
enum smtp_connection_security{
|
||||
#ifdef SMTP_OPENSSL
|
||||
/**
|
||||
* First connect without encryption, then negotiate an encrypted connection
|
||||
* by issuing a STARTTLS command.
|
||||
*
|
||||
* Typically used when connecting to a mail server on port 25 or 587.
|
||||
*/
|
||||
SMTP_SECURITY_STARTTLS = 0,
|
||||
|
||||
/**
|
||||
* Use TLS when initially connecting to server.
|
||||
*
|
||||
* Typically used when connecting to a mail server on port 465.
|
||||
*/
|
||||
SMTP_SECURITY_TLS = 1,
|
||||
#endif /* SMTP_OPENSSL */
|
||||
|
||||
/**
|
||||
* Do not use TLS encryption.
|
||||
*
|
||||
* Not recommended unless connecting to the SMTP server locally.
|
||||
*/
|
||||
SMTP_SECURITY_NONE = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* List of supported methods for authenticating a mail user account on
|
||||
* the server.
|
||||
*/
|
||||
enum smtp_authentication_method{
|
||||
#ifdef SMTP_OPENSSL
|
||||
/**
|
||||
* Use HMAC-MD5.
|
||||
*/
|
||||
SMTP_AUTH_CRAM_MD5 = 0,
|
||||
#endif /* SMTP_OPENSSL */
|
||||
/**
|
||||
* No authentication required.
|
||||
*
|
||||
* Some servers support this option if connecting locally.
|
||||
*/
|
||||
SMTP_AUTH_NONE = 1,
|
||||
|
||||
/**
|
||||
* Authenticate using base64 user and password.
|
||||
*/
|
||||
SMTP_AUTH_PLAIN = 2,
|
||||
|
||||
/**
|
||||
* Another base64 authentication method, similar to SMTP_AUTH_PLAIN.
|
||||
*/
|
||||
SMTP_AUTH_LOGIN = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* Special flags defining certain behaviors for the SMTP client context.
|
||||
*/
|
||||
enum smtp_flag{
|
||||
/**
|
||||
* Print client and server communication on stderr.
|
||||
*/
|
||||
SMTP_DEBUG = 1 << 0,
|
||||
|
||||
/**
|
||||
* Do not verify TLS certificate.
|
||||
*
|
||||
* By default, the TLS handshake function will check if a certificate
|
||||
* has expired or if using a self-signed certificate. Either of those
|
||||
* conditions will cause the connection to fail. This option allows the
|
||||
* connection to proceed even if those checks fail.
|
||||
*/
|
||||
SMTP_NO_CERT_VERIFY = 1 << 1
|
||||
};
|
||||
|
||||
struct smtp;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* Open a connection to an SMTP server and return the context.
|
||||
*
|
||||
* After successfully connecting and performing a handshake with the
|
||||
* SMTP server, this will return a valid SMTP client context that
|
||||
* the application can use in the other library functions.
|
||||
*
|
||||
* This always returns a valid SMTP client context even if
|
||||
* the server connection or memory allocation fails. In this scenario, the
|
||||
* error status will continue to propagate to future library calls for
|
||||
* the SMTP context while in this failure mode.
|
||||
*
|
||||
* This function will ignore the SIGPIPE signal. Applications that require a
|
||||
* handler for that signal should set it up after calling this function.
|
||||
*
|
||||
* @param[in] server Server name or IP address.
|
||||
* @param[in] port Server port number.
|
||||
* @param[in] connection_security See @ref smtp_connection_security.
|
||||
* @param[in] flags See @ref smtp_flag.
|
||||
* @param[in] cafile Path to certificate file, or NULL to use
|
||||
* certificates in the default path.
|
||||
* @param[out] smtp Pointer to a new SMTP context. When
|
||||
* finished, the caller must free this
|
||||
* context using @ref smtp_close.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_open(const char *const server,
|
||||
const char *const port,
|
||||
enum smtp_connection_security connection_security,
|
||||
enum smtp_flag flags,
|
||||
const char *const cafile,
|
||||
struct smtp **smtp);
|
||||
|
||||
/**
|
||||
* Authenticate the user using one of the methods listed in
|
||||
* @ref smtp_authentication_method.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @param[in] auth_method See @ref smtp_authentication_method.
|
||||
* @param[in] user SMTP user name.
|
||||
* @param[in] pass SMTP password.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_auth(struct smtp *const smtp,
|
||||
enum smtp_authentication_method auth_method,
|
||||
const char *const user,
|
||||
const char *const pass);
|
||||
|
||||
/**
|
||||
* Sends an email using the addresses, attachments, and headers defined
|
||||
* in the current SMTP context.
|
||||
*
|
||||
* The caller must call the @ref smtp_open function prior to this.
|
||||
*
|
||||
* The 'Date' header will automatically get generated here if it hasn't
|
||||
* already been set using @ref smtp_header_add.
|
||||
*
|
||||
* If the application overrides the default 'Content-Type' header, then
|
||||
* this function will output the @p body as raw data just below the email
|
||||
* headers, and it will not output the attachments added using the
|
||||
* smtp_attachment_add_* functions. In other words, the application must
|
||||
* create its own MIME sections (if needed) when overriding the
|
||||
* 'Content-Type' header.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @param[in] body Null-terminated string to send in the email body.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_mail(struct smtp *const smtp,
|
||||
const char *const body);
|
||||
|
||||
/**
|
||||
* Close the SMTP connection and frees all resources held by the
|
||||
* SMTP context.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_close(struct smtp *smtp);
|
||||
|
||||
/**
|
||||
* Get the current status/error code.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_status_code_get(const struct smtp *const smtp);
|
||||
|
||||
/**
|
||||
* Clear the current error code set in the SMTP client context.
|
||||
*
|
||||
* @param[in,out] smtp SMTP client context.
|
||||
* @return Previous error code before clearing.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_status_code_clear(struct smtp *const smtp);
|
||||
|
||||
/**
|
||||
* Set the error status of the SMTP client context and return the same code.
|
||||
*
|
||||
* This allows the caller to clear an error status to SMTP_STATUS_OK
|
||||
* so that previous errors will stop propagating. However, this will only
|
||||
* work correctly for clearing the SMTP_STATUS_PARAM and SMTP_STATUS_FILE
|
||||
* errors. Do not use this to clear any other error codes.
|
||||
*
|
||||
* @deprecated Use @ref smtp_status_code_clear instead.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @param[in] new_status_code See @ref smtp_status_code.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_status_code_set(struct smtp *const smtp,
|
||||
enum smtp_status_code new_status_code);
|
||||
|
||||
/**
|
||||
* Convert a standard SMTP client status code to a descriptive string.
|
||||
*
|
||||
* @param[in] status_code Status code returned from one of the other
|
||||
* library functions.
|
||||
* @return String containing a description of the @p status_code. The caller
|
||||
* must not free or modify this string.
|
||||
*/
|
||||
const char *
|
||||
smtp_status_code_errstr(enum smtp_status_code status_code);
|
||||
|
||||
/**
|
||||
* Add a key/value header to the header list in the SMTP context.
|
||||
*
|
||||
* If adding a header with an existing key, this will insert instead of
|
||||
* replacing the existing header. See @ref smtp_header_clear_all.
|
||||
*
|
||||
* See @ref smtp_mail when overriding the default 'Content-Type' header.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @param[in] key Key name for new header. It must consist only of
|
||||
* printable US-ASCII characters except colon.
|
||||
* @param[in] value Value for new header. It must consist only of printable
|
||||
* US-ASCII, space, or horizontal tab. If set to NULL,
|
||||
* this will prevent the header from printing out.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_header_add(struct smtp *const smtp,
|
||||
const char *const key,
|
||||
const char *const value);
|
||||
|
||||
/**
|
||||
* Free all memory related to email headers.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
*/
|
||||
void
|
||||
smtp_header_clear_all(struct smtp *const smtp);
|
||||
|
||||
/**
|
||||
* Add a FROM, TO, CC, or BCC address destination to this SMTP context.
|
||||
*
|
||||
* @note Some SMTP servers may reject over 100 recipients.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @param[in] type See @ref smtp_address_type.
|
||||
* @param[in] email The email address of the party. Must consist only of
|
||||
* printable characters excluding the angle brackets
|
||||
* (<) and (>).
|
||||
* @param[in] name Name or description of the party. Must consist only of
|
||||
* printable characters, excluding the quote characters. If
|
||||
* set to NULL or empty string, no name will get associated
|
||||
* with this email.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_address_add(struct smtp *const smtp,
|
||||
enum smtp_address_type type,
|
||||
const char *const email,
|
||||
const char *const name);
|
||||
|
||||
/**
|
||||
* Free all memory related to the address list.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
*/
|
||||
void
|
||||
smtp_address_clear_all(struct smtp *const smtp);
|
||||
|
||||
/**
|
||||
* Add a file attachment from a path.
|
||||
*
|
||||
* See @ref smtp_attachment_add_mem for more details.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @param[in] name Filename of the attachment shown to recipients. Must
|
||||
* consist only of printable ASCII characters, excluding
|
||||
* the quote characters (') and (").
|
||||
* @param[in] path Path to file.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_attachment_add_path(struct smtp *const smtp,
|
||||
const char *const name,
|
||||
const char *const path);
|
||||
|
||||
/**
|
||||
* Add an attachment using a file pointer.
|
||||
*
|
||||
* See @ref smtp_attachment_add_mem for more details.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @param[in] name Filename of the attachment shown to recipients. Must
|
||||
* consist only of printable ASCII characters, excluding
|
||||
* the quote characters (') and (").
|
||||
* @param[in] fp File pointer already opened by the caller.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_attachment_add_fp(struct smtp *const smtp,
|
||||
const char *const name,
|
||||
FILE *fp);
|
||||
|
||||
/**
|
||||
* Add a MIME attachment to this SMTP context with the data retrieved
|
||||
* from memory.
|
||||
*
|
||||
* The attachment data will get base64 encoded before sending to the server.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
* @param[in] name Filename of the attachment shown to recipients. Must
|
||||
* consist only of printable ASCII characters, excluding
|
||||
* the quote characters (') and (").
|
||||
* @param[in] data Raw attachment data stored in memory.
|
||||
* @param[in] datasz Number of bytes in @p data, or -1 if data
|
||||
* null-terminated.
|
||||
* @return See @ref smtp_status_code.
|
||||
*/
|
||||
enum smtp_status_code
|
||||
smtp_attachment_add_mem(struct smtp *const smtp,
|
||||
const char *const name,
|
||||
const void *const data,
|
||||
size_t datasz);
|
||||
|
||||
/**
|
||||
* Remove all attachments from the SMTP client context.
|
||||
*
|
||||
* @param[in] smtp SMTP client context.
|
||||
*/
|
||||
void
|
||||
smtp_attachment_clear_all(struct smtp *const smtp);
|
||||
|
||||
|
||||
/*
|
||||
* The SMTP_INTERNAL DEFINE section contains definitions that get used
|
||||
* internally by the SMTP client library.
|
||||
*/
|
||||
#ifdef SMTP_INTERNAL_DEFINE
|
||||
/**
|
||||
* SMTP codes returned by the server and parsed by the client.
|
||||
*/
|
||||
enum smtp_result_code{
|
||||
/**
|
||||
* Client error code which does not get set by the server.
|
||||
*/
|
||||
SMTP_INTERNAL_ERROR = -1,
|
||||
|
||||
/**
|
||||
* Returned when ready to begin processing next step.
|
||||
*/
|
||||
SMTP_READY = 220,
|
||||
|
||||
/**
|
||||
* Returned in response to QUIT.
|
||||
*/
|
||||
SMTP_CLOSE = 221,
|
||||
|
||||
/**
|
||||
* Returned if client successfully authenticates.
|
||||
*/
|
||||
SMTP_AUTH_SUCCESS = 235,
|
||||
|
||||
/**
|
||||
* Returned when some commands successfully complete.
|
||||
*/
|
||||
SMTP_DONE = 250,
|
||||
|
||||
/**
|
||||
* Returned for some multi-line authentication mechanisms where this code
|
||||
* indicates the next stage in the authentication step.
|
||||
*/
|
||||
SMTP_AUTH_CONTINUE = 334,
|
||||
|
||||
/**
|
||||
* Returned in response to DATA command.
|
||||
*/
|
||||
SMTP_BEGIN_MAIL = 354
|
||||
};
|
||||
|
||||
/**
|
||||
* Used for parsing out the responses from the SMTP server.
|
||||
*
|
||||
* For example, if the server sends back '250-STARTTLS', then code would
|
||||
* get set to 250, more would get set to 1, and text would get set to STARTTLS.
|
||||
*/
|
||||
struct smtp_command{
|
||||
/**
|
||||
* Result code converted to an integer.
|
||||
*/
|
||||
enum smtp_result_code code;
|
||||
|
||||
/**
|
||||
* Indicates if more server commands follow.
|
||||
*
|
||||
* This will get set to 1 if the fourth character in the response line
|
||||
* contains a '-', otherwise this will get set to 0.
|
||||
*/
|
||||
int more;
|
||||
|
||||
/**
|
||||
* The text shown after the status code.
|
||||
*/
|
||||
const char *text;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return codes for the getdelim interface which allows the caller to check
|
||||
* if more delimited lines can get processed.
|
||||
*/
|
||||
enum str_getdelim_retcode{
|
||||
/**
|
||||
* An error occurred during the getdelim processing.
|
||||
*/
|
||||
STRING_GETDELIMFD_ERROR = -1,
|
||||
|
||||
/**
|
||||
* Found a new line and can process more lines in the next call.
|
||||
*/
|
||||
STRING_GETDELIMFD_NEXT = 0,
|
||||
|
||||
/**
|
||||
* Found a new line and unable to read any more lines at this time.
|
||||
*/
|
||||
STRING_GETDELIMFD_DONE = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* Data structure for read buffer and line parsing.
|
||||
*
|
||||
* This assists with getting and parsing the server response lines.
|
||||
*/
|
||||
struct str_getdelimfd{
|
||||
/**
|
||||
* Read buffer which may include bytes past the delimiter.
|
||||
*/
|
||||
char *_buf;
|
||||
|
||||
/**
|
||||
* Number of allocated bytes in the read buffer.
|
||||
*/
|
||||
size_t _bufsz;
|
||||
|
||||
/**
|
||||
* Number of actual stored bytes in the read buffer.
|
||||
*/
|
||||
size_t _buf_len;
|
||||
|
||||
/**
|
||||
* Current line containing the text up to the delimiter.
|
||||
*/
|
||||
char *line;
|
||||
|
||||
/**
|
||||
* Number of stored bytes in the line buffer.
|
||||
*/
|
||||
size_t line_len;
|
||||
|
||||
/**
|
||||
* Function pointer to a custom read function for the
|
||||
* @ref smtp_str_getdelimfd interface.
|
||||
*
|
||||
* This function prototype has similar semantics to the read function.
|
||||
* The @p gdfd parameter allows the custom function to pull the user_data
|
||||
* info from the @ref str_getdelimfd struct which can contain file pointer,
|
||||
* socket connection, etc.
|
||||
*/
|
||||
long (*getdelimfd_read)(struct str_getdelimfd *const gdfd,
|
||||
void *buf,
|
||||
size_t count);
|
||||
|
||||
/**
|
||||
* User data which gets sent to the read handler function.
|
||||
*/
|
||||
void *user_data;
|
||||
|
||||
/**
|
||||
* Character delimiter used for determining line separation.
|
||||
*/
|
||||
int delim;
|
||||
|
||||
/**
|
||||
* Padding structure to align.
|
||||
*/
|
||||
char pad[4];
|
||||
};
|
||||
|
||||
#endif /* SMTP_INTERNAL_DEFINE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* SMTP_H */
|
||||
|
||||
62
src/tools/web_api/dep/smtp-client/test/example_html.c
Normal file
62
src/tools/web_api/dep/smtp-client/test/example_html.c
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <stdio.h>
|
||||
#include "smtp.h"
|
||||
#define MAIL_SERVER "localhost"
|
||||
#define MAIL_PORT "587"
|
||||
#define MAIL_CONNECTION_SECURITY SMTP_SECURITY_NONE
|
||||
#define MAIL_FLAGS SMTP_DEBUG
|
||||
#define MAIL_CAFILE NULL
|
||||
#define MAIL_AUTH SMTP_AUTH_NONE
|
||||
#define MAIL_USER "mail@somnisoft.com"
|
||||
#define MAIL_PASS "password"
|
||||
#define MAIL_FROM "mail@somnisoft.com"
|
||||
#define MAIL_FROM_NAME "From Name"
|
||||
#define MAIL_SUBJECT "Subject Line"
|
||||
#define MAIL_TO "mail@somnisoft.com"
|
||||
#define MAIL_TO_NAME "To Name"
|
||||
int main(void){
|
||||
struct smtp *smtp;
|
||||
enum smtp_status_code rc;
|
||||
const char *const email_body =
|
||||
"<html>\n"
|
||||
" <head><title>HTML Email</title></head>\n"
|
||||
" <body>\n"
|
||||
" <h1>H1</h1>\n"
|
||||
" <h2>H2</h1>\n"
|
||||
" <h3>H3</h1>\n"
|
||||
" <h4>H4</h1>\n"
|
||||
" <h5>H5</h1>\n"
|
||||
" <h6>H6</h1>\n"
|
||||
" </body>\n"
|
||||
"</html>\n";
|
||||
smtp_open(MAIL_SERVER,
|
||||
MAIL_PORT,
|
||||
MAIL_CONNECTION_SECURITY,
|
||||
MAIL_FLAGS,
|
||||
MAIL_CAFILE,
|
||||
&smtp);
|
||||
smtp_auth(smtp,
|
||||
MAIL_AUTH,
|
||||
MAIL_USER,
|
||||
MAIL_PASS);
|
||||
smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_FROM,
|
||||
MAIL_FROM,
|
||||
MAIL_FROM_NAME);
|
||||
smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_TO,
|
||||
MAIL_TO,
|
||||
MAIL_TO_NAME);
|
||||
smtp_header_add(smtp,
|
||||
"Subject",
|
||||
MAIL_SUBJECT);
|
||||
smtp_header_add(smtp,
|
||||
"Content-Type",
|
||||
"text/html");
|
||||
smtp_mail(smtp, email_body);
|
||||
rc = smtp_close(smtp);
|
||||
if(rc != SMTP_STATUS_OK){
|
||||
fprintf(stderr, "smtp failed: %s\n", smtp_status_code_errstr(rc));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
55
src/tools/web_api/dep/smtp-client/test/example_simple.c
Normal file
55
src/tools/web_api/dep/smtp-client/test/example_simple.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include "smtp.h"
|
||||
#define MAIL_SERVER "mail.example.com"
|
||||
#define MAIL_PORT "587"
|
||||
#define MAIL_CONNECTION_SECURITY SMTP_SECURITY_STARTTLS
|
||||
#define MAIL_FLAGS (SMTP_DEBUG | \
|
||||
SMTP_NO_CERT_VERIFY) /* Do not verify cert. */
|
||||
#define MAIL_CAFILE NULL
|
||||
#define MAIL_AUTH SMTP_AUTH_PLAIN
|
||||
#define MAIL_USER "mail@example.com"
|
||||
#define MAIL_PASS "password"
|
||||
#define MAIL_FROM "mail@example.com"
|
||||
#define MAIL_FROM_NAME "From Name"
|
||||
#define MAIL_SUBJECT "Subject Line"
|
||||
#define MAIL_BODY "Email Body"
|
||||
#define MAIL_TO "to@example.com"
|
||||
#define MAIL_TO_NAME "To Name"
|
||||
int main(void)
|
||||
{
|
||||
struct smtp *smtp;
|
||||
int rc;
|
||||
rc = smtp_open(MAIL_SERVER,
|
||||
MAIL_PORT,
|
||||
MAIL_CONNECTION_SECURITY,
|
||||
MAIL_FLAGS,
|
||||
MAIL_CAFILE,
|
||||
&smtp);
|
||||
rc = smtp_auth(smtp,
|
||||
MAIL_AUTH,
|
||||
MAIL_USER,
|
||||
MAIL_PASS);
|
||||
rc = smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_FROM,
|
||||
MAIL_FROM,
|
||||
MAIL_FROM_NAME);
|
||||
rc = smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_TO,
|
||||
MAIL_TO,
|
||||
MAIL_TO_NAME);
|
||||
rc = smtp_header_add(smtp,
|
||||
"Subject",
|
||||
MAIL_SUBJECT);
|
||||
rc = smtp_attachment_add_mem(smtp,
|
||||
"test.txt",
|
||||
"Test email attachment.",
|
||||
-1);
|
||||
rc = smtp_mail(smtp,
|
||||
MAIL_BODY);
|
||||
rc = smtp_close(smtp);
|
||||
if(rc != SMTP_STATUS_OK){
|
||||
fprintf(stderr, "smtp failed: %s\n", smtp_status_code_errstr(rc));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
819
src/tools/web_api/dep/smtp-client/test/seams.c
Normal file
819
src/tools/web_api/dep/smtp-client/test/seams.c
Normal file
@@ -0,0 +1,819 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Test seams for the smtp-client library.
|
||||
* @author James Humphrey (mail@somnisoft.com)
|
||||
* @version 1.00
|
||||
*
|
||||
* Used by the smtp-client testing framework to inject specific return values
|
||||
* by some standard library functions. This makes it possible to test less
|
||||
* common errors like out of memory conditions and input/output errors.
|
||||
*
|
||||
* This software has been placed into the public domain using CC0.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "test.h"
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_bio_new_socket_ctr and
|
||||
* @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_bio_new_socket_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_bio_should_retry_ctr and
|
||||
* @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_bio_should_retry_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_bio_should_retry_rc.
|
||||
*/
|
||||
int g_smtp_test_err_bio_should_retry_rc = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_calloc_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_calloc_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_close_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_close_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_connect_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_connect_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_err_peek_error_ctr and
|
||||
* @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_err_peek_error_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_fclose_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_fclose_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_ferror_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_ferror_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_gmtime_r_ctr @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_gmtime_r_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_hmac_ctr @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_hmac_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_localtime_r_ctr and
|
||||
* @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_localtime_r_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_malloc_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_malloc_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_mktime_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_mktime_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_realloc_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_realloc_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_recv_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_recv_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_recv_rc.
|
||||
*/
|
||||
int g_smtp_test_err_recv_rc = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_recv_bytes and @ref test_seams_countdown_global.
|
||||
*/
|
||||
char g_smtp_test_err_recv_bytes[90] = {0};
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_select_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_select_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_send_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_send_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_send_one_byte.
|
||||
*/
|
||||
int g_smtp_test_send_one_byte = 0;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_si_add_size_t_ctr
|
||||
* and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_si_add_size_t_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_si_sub_size_t_ctr
|
||||
* and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_si_sub_size_t_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_si_mul_size_t_ctr
|
||||
* and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_si_mul_size_t_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_socket_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_socket_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_ssl_connect_ctr and
|
||||
* @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_ssl_connect_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_ssl_ctx_new_ctr and
|
||||
* @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_ssl_ctx_new_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_ssl_do_handshake_ctr and
|
||||
* @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_ssl_do_handshake_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_ssl_get_peer_certificate_ctr and
|
||||
* @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_ssl_get_peer_certificate_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_x509_check_host_ctr and
|
||||
* @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_x509_check_host_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_ssl_new_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_ssl_new_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_ssl_read_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_ssl_read_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_ssl_write_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_ssl_write_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_sprintf_ctr and @ref test_seams_countdown_global.
|
||||
*/
|
||||
int g_smtp_test_err_sprintf_ctr = -1;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_err_sprintf_rc.
|
||||
*/
|
||||
int g_smtp_test_err_sprintf_rc = 0;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_strlen_custom_ret.
|
||||
*/
|
||||
int g_smtp_test_strlen_custom_ret = 0;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_strlen_ret_value.
|
||||
*/
|
||||
size_t g_smtp_test_strlen_ret_value = 0;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_time_custom_ret.
|
||||
*/
|
||||
int g_smtp_test_time_custom_ret = 0;
|
||||
|
||||
/**
|
||||
* See @ref g_smtp_test_time_ret_value.
|
||||
*/
|
||||
time_t g_smtp_test_time_ret_value = 0;
|
||||
|
||||
/**
|
||||
* Decrement an error counter until it reaches -1.
|
||||
*
|
||||
* Once a counter reaches -1, it will return a successful response (1). This
|
||||
* typically gets used to denote when to cause a function to fail. For example,
|
||||
* the unit test or functional test might need to cause the realloc() function
|
||||
* to fail after calling it the third time.
|
||||
*
|
||||
* @param[in,out] test_err_ctr Integer counter to decrement.
|
||||
* @retval 0 The counter has been decremented, but did not reach -1 yet.
|
||||
* @retval 1 The counter has reached -1.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_dec_err_ctr(int *const test_err_ctr){
|
||||
if(*test_err_ctr >= 0){
|
||||
*test_err_ctr -= 1;
|
||||
if(*test_err_ctr < 0){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when BIO_new_socket() fails.
|
||||
*
|
||||
* @param[in] sock Existing socket to attach the BIO to.
|
||||
* @param[in] close_flag Close flag for new BIO.
|
||||
* @retval BIO* New BIO created on existing socket.
|
||||
* @retval NULL Failed to create the new BIO.
|
||||
*/
|
||||
BIO *
|
||||
smtp_test_seam_bio_new_socket(int sock,
|
||||
int close_flag){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_bio_new_socket_ctr)){
|
||||
return NULL;
|
||||
}
|
||||
return BIO_new_socket(sock, close_flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when BIO_should_retry() fails.
|
||||
*
|
||||
* @param[in] bio Existing BIO connection.
|
||||
* @retval 0 The error condition does not allow a retry.
|
||||
* @retval 1 The error condition allows a retry.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_bio_should_retry(BIO *bio){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_bio_should_retry_ctr)){
|
||||
return 0;
|
||||
}
|
||||
if(g_smtp_test_err_bio_should_retry_rc != -1){
|
||||
return g_smtp_test_err_bio_should_retry_rc;
|
||||
}
|
||||
return BIO_should_retry(bio);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when calloc() fails.
|
||||
*
|
||||
* @param[in] nelem Number of elements to allocate.
|
||||
* @param[in] elsize Size of each element to allocate.
|
||||
* @retval void* Pointer to new allocated memory.
|
||||
* @retval NULL Memory allocation failed.
|
||||
*/
|
||||
void *
|
||||
smtp_test_seam_calloc(size_t nelem,
|
||||
size_t elsize){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_calloc_ctr)){
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return calloc(nelem, elsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when close() fails.
|
||||
*
|
||||
* @param[in] fildes Socket file descriptor to close.
|
||||
* @retval 0 Successfully closed file descriptor.
|
||||
* @retval -1 Failed to close file descriptor.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_close(int fildes){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_close_ctr)){
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
return close(fildes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when connect() fails.
|
||||
*
|
||||
* @param[in] socket Socket connection.
|
||||
* @param[in] address Network address of peer.
|
||||
* @param[in] address_len Number of bytes in @p address.
|
||||
* @retval 0 Successfully connected to the peer.
|
||||
* @retval -1 Failed to connect to the peer.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_connect(int socket,
|
||||
const struct sockaddr *address,
|
||||
socklen_t address_len){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_connect_ctr)){
|
||||
errno = ECONNREFUSED;
|
||||
return -1;
|
||||
}
|
||||
return connect(socket, address, address_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when ERR_peek_error() returns a failure
|
||||
* code.
|
||||
*
|
||||
* @retval 0 No error code on the error queue.
|
||||
* @retval !0 An error code exists on the error queue.
|
||||
*/
|
||||
unsigned long
|
||||
smtp_test_seam_err_peek_error(void){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_err_peek_error_ctr)){
|
||||
return 1;
|
||||
}
|
||||
return ERR_peek_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when fclose() fails.
|
||||
*
|
||||
* @param[in] stream File stream to close.
|
||||
* @retval 0 Successfully closed the file stream.
|
||||
* @retval EOF An error occurred while closing the file stream.
|
||||
*/
|
||||
int smtp_test_seam_fclose(FILE *stream){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_fclose_ctr)){
|
||||
errno = EBADF;
|
||||
return EOF;
|
||||
}
|
||||
return fclose(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control the file stream error indicator return
|
||||
* value in ferror().
|
||||
*
|
||||
* @param[in] stream Check for errors on this file stream.
|
||||
* @retval 0 No errors detected on the file stream.
|
||||
* @retval 1 An error occurred during a file stream operation.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_ferror(FILE *stream){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_ferror_ctr)){
|
||||
return 1;
|
||||
}
|
||||
return ferror(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when gmtime_r() fails.
|
||||
*
|
||||
* @param[in] timep Time value to convert to a struct tm.
|
||||
* @param[out] result Converts the @p timep value into a UTC tm structure
|
||||
* value and stores the results in this pointer.
|
||||
* @retval tm* time_t value converted to a tm structure value.
|
||||
* @retval NULL An error occurred while converting the time.
|
||||
*/
|
||||
struct tm *
|
||||
smtp_test_seam_gmtime_r(const time_t *timep,
|
||||
struct tm *result){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_gmtime_r_ctr)){
|
||||
return NULL;
|
||||
}
|
||||
return gmtime_r(timep, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when HMAC() fails.
|
||||
*
|
||||
* @param[in] evp_md Hash function.
|
||||
* @param[in] key Hash key.
|
||||
* @param[in] key_len Number of bytes in @p key.
|
||||
* @param[in] d Message data.
|
||||
* @param[in] n Number of bytes in @p d.
|
||||
* @param[out] md The computed message authentication code.
|
||||
* @param[in] md_len Number of bytes in @p md.
|
||||
* @retval uchar* Pointer to @p md.
|
||||
* @retval NULL An error occurred.
|
||||
*/
|
||||
unsigned char *
|
||||
smtp_test_seam_hmac(const EVP_MD *evp_md,
|
||||
const void *key,
|
||||
int key_len,
|
||||
const unsigned char *d,
|
||||
size_t n,
|
||||
unsigned char *md,
|
||||
unsigned int *md_len){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_hmac_ctr)){
|
||||
return NULL;
|
||||
}
|
||||
return HMAC(evp_md, key, key_len, d, n, md, md_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when localtime_r() fails.
|
||||
*
|
||||
* @param[in] timep Time value to convert to a struct tm.
|
||||
* @param[out] result Converts the @p timep value into a local time tm
|
||||
* structure value and stores the results in this pointer.
|
||||
* @retval tm* time_t value converted to a tm structure value.
|
||||
* @retval NULL An error occurred while converting the time.
|
||||
*/
|
||||
struct tm *
|
||||
smtp_test_seam_localtime_r(const time_t *timep,
|
||||
struct tm *result){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_localtime_r_ctr)){
|
||||
return NULL;
|
||||
}
|
||||
return localtime_r(timep, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when malloc() fails.
|
||||
*
|
||||
* @param[in] size Number of bytes to allocate.
|
||||
* @retval void* Pointer to new allocated memory.
|
||||
* @retval NULL Memory allocation failed.
|
||||
*/
|
||||
void *
|
||||
smtp_test_seam_malloc(size_t size){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_malloc_ctr)){
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when mktime() fails.
|
||||
*
|
||||
* @param[in] timeptr tm data structure to convert to time_t.
|
||||
* @retval >=0 Time since the epoch.
|
||||
* @retval -1 Failed to convert the time.
|
||||
*/
|
||||
time_t
|
||||
smtp_test_seam_mktime(struct tm *timeptr){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_mktime_ctr)){
|
||||
return -1;
|
||||
}
|
||||
return mktime(timeptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when realloc() fails.
|
||||
*
|
||||
* @param[in] ptr Previously allocated memory or NULL memory has not been
|
||||
* allocated yet.
|
||||
* @param[in] size Number of bytes to reallocate.
|
||||
* @retval void* Pointer to new allocated memory.
|
||||
* @retval NULL Memory allocation failed.
|
||||
*/
|
||||
void *
|
||||
smtp_test_seam_realloc(void *ptr,
|
||||
size_t size){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_realloc_ctr)){
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when recv() fails.
|
||||
*
|
||||
* @param[in] socket TCP network socket.
|
||||
* @param[in] buffer Store received data in this buffer.
|
||||
* @param[in] length Number of bytes in @p buffer.
|
||||
* @param[in] flags Set this to 0.
|
||||
* @retval >=0 Number of bytes received.
|
||||
* @retval -1 Failed to receive bytes over the network.
|
||||
*/
|
||||
long
|
||||
smtp_test_seam_recv(int socket,
|
||||
void *buffer,
|
||||
size_t length,
|
||||
int flags){
|
||||
size_t bytes_inject_len;
|
||||
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_recv_ctr)){
|
||||
if(g_smtp_test_err_recv_rc != -1){
|
||||
return g_smtp_test_err_recv_rc;
|
||||
}
|
||||
if(*g_smtp_test_err_recv_bytes){
|
||||
bytes_inject_len = strlen(g_smtp_test_err_recv_bytes);
|
||||
assert(bytes_inject_len < length && bytes_inject_len < LONG_MAX);
|
||||
memcpy(buffer, g_smtp_test_err_recv_bytes, bytes_inject_len);
|
||||
return (long)bytes_inject_len;
|
||||
}
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
return recv(socket, buffer, length, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when select() fails.
|
||||
*
|
||||
* @param[in] nfds Check for file descriptors in range 0 to (@p nfds - 1)
|
||||
* which have any of the read/write/error conditions.
|
||||
* @param[in] readfds Checks for file descriptors in fd_set that have bytes
|
||||
* ready for reading.
|
||||
* @param[in] writefds Checks for file descriptors in fd_set that have bytes
|
||||
* ready for writing.
|
||||
* @param[in] errorfds Checks for file descriptors in fd_set that have errors
|
||||
* pending.
|
||||
* @param[in] timeout Wait for the read/write/error conditions in blocking
|
||||
* mode until this timeout or an interrupt occurs.
|
||||
* @retval >=0 Number of bits set in the bitmask.
|
||||
* @retval -1 An error occurred.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_select(int nfds,
|
||||
fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
fd_set *errorfds,
|
||||
struct timeval *timeout){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_select_ctr)){
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
return select(nfds, readfds, writefds, errorfds, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when send() fails.
|
||||
*
|
||||
* @param[in] socket TCP network socket.
|
||||
* @param[in] buffer Data to send over the network.
|
||||
* @param[in] length Number of bytes in @p buffer.
|
||||
* @param[in] flags Set this to 0.
|
||||
* @retval >=0 Number of bytes sent.
|
||||
* @retval -1 Failed to send bytes over the network.
|
||||
*/
|
||||
ssize_t
|
||||
smtp_test_seam_send(int socket,
|
||||
const void *buffer,
|
||||
size_t length,
|
||||
int flags){
|
||||
long sent_bytes;
|
||||
size_t bytes_to_send;
|
||||
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_send_ctr)){
|
||||
errno = EBADF;
|
||||
sent_bytes = -1;
|
||||
}
|
||||
else{
|
||||
bytes_to_send = length;
|
||||
if(g_smtp_test_send_one_byte){
|
||||
bytes_to_send = 1;
|
||||
}
|
||||
sent_bytes = send(socket, buffer, bytes_to_send, flags);
|
||||
}
|
||||
return sent_bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when socket() fails.
|
||||
*
|
||||
* @param[in] domain Socket domain.
|
||||
* @param[in] type Socket type.
|
||||
* @param[in] protocol Socket protocol.
|
||||
* @retval !(-1) The file descriptor for the new socket.
|
||||
* @retval -1 Failed to create the socket.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_socket(int domain,
|
||||
int type,
|
||||
int protocol){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_socket_ctr)){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return socket(domain, type, protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when SSL_connect() fails.
|
||||
*
|
||||
* @param[in] ssl OpenSSL handle.
|
||||
* @retval 1 TLS connection handshake successful.
|
||||
* @retval <1 TLS connection handshake failed.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_ssl_connect(SSL *ssl){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_ssl_connect_ctr)){
|
||||
return 0;
|
||||
}
|
||||
return SSL_connect(ssl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when SSL_CTX_new() fails.
|
||||
*
|
||||
* @param[in] method TLS connection method.
|
||||
* @retval SSL_CTX* Pointer to new TLS context.
|
||||
* @retval NULL Failed to create new TLS context.
|
||||
*/
|
||||
SSL_CTX *
|
||||
smtp_test_seam_ssl_ctx_new(const SSL_METHOD *method){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_ssl_ctx_new_ctr)){
|
||||
return NULL;
|
||||
}
|
||||
return SSL_CTX_new(method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when SSL_do_handshake() fails.
|
||||
*
|
||||
* @param[in] ssl OpenSSL handle.
|
||||
* @retval 1 TLS handshake successful.
|
||||
* @retval <1 TLS handshake failed.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_ssl_do_handshake(SSL *ssl){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_ssl_do_handshake_ctr)){
|
||||
return 0;
|
||||
}
|
||||
return SSL_do_handshake(ssl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when SSL_get_peer_certificate() fails.
|
||||
*
|
||||
* @param[in] ssl OpenSSL handle.
|
||||
* @retval X509* Peer certficate which must get freed by using X509_free().
|
||||
* @retval NULL Failed to get the peer certificate.
|
||||
*/
|
||||
X509 *
|
||||
smtp_test_seam_ssl_get_peer_certificate(const SSL *ssl){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_ssl_get_peer_certificate_ctr)){
|
||||
return NULL;
|
||||
}
|
||||
return SSL_get_peer_certificate(ssl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when X509_check_host() fails.
|
||||
*
|
||||
* @param[in] cert X509 certificate handle.
|
||||
* @param[in] name Server name.
|
||||
* @param[in] namelen Number of characters in @p name or 0 if null-terminated.
|
||||
* @param[in] flags Usually set to 0.
|
||||
* @param[in] peername Pointer to CN from certificate stored in this buffer
|
||||
* if not NULL.
|
||||
* @retval 1 Successful host check.
|
||||
* @retval 0 Failed host check.
|
||||
* @retval -1 Internal error.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_x509_check_host(X509 *cert,
|
||||
const char *name,
|
||||
size_t namelen,
|
||||
unsigned int flags,
|
||||
char **peername){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_x509_check_host_ctr)){
|
||||
return -1;
|
||||
}
|
||||
return X509_check_host(cert, name, namelen, flags, peername);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when SSL_new() fails.
|
||||
*
|
||||
* @param[in] ctx OpenSSL TLS context.
|
||||
* @retval SSL* Pointer to a new TLS context.
|
||||
* @retval NULL Failed to create new TLS context.
|
||||
*/
|
||||
SSL *
|
||||
smtp_test_seam_ssl_new(SSL_CTX *ctx){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_ssl_new_ctr)){
|
||||
return NULL;
|
||||
}
|
||||
return SSL_new(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when SSL_read() fails.
|
||||
*
|
||||
* @param[in] ssl OpenSSL TLS object.
|
||||
* @param[in] buf Store received data in this buffer.
|
||||
* @param[in] num Number of bytes in @p buf.
|
||||
* @retval >0 Number of bytes successfully read from the TLS connection.
|
||||
* @retval <=0 Failed to read bytes on the TLS connection.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_ssl_read(SSL *ssl,
|
||||
void *buf,
|
||||
int num){
|
||||
size_t bytes_inject_len;
|
||||
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_ssl_read_ctr)){
|
||||
if(*g_smtp_test_err_recv_bytes){
|
||||
bytes_inject_len = strlen(g_smtp_test_err_recv_bytes);
|
||||
assert(bytes_inject_len < (size_t)num && bytes_inject_len < INT_MAX);
|
||||
memcpy(buf, g_smtp_test_err_recv_bytes, bytes_inject_len);
|
||||
return (int)bytes_inject_len;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return SSL_read(ssl, buf, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when SSL_write() fails.
|
||||
*
|
||||
* @param[in] ssl OpenSSL TLS object.
|
||||
* @param[in] buf Data to write to the TLS connection.
|
||||
* @param[in] num Number of bytes in @p buf.
|
||||
* @retval >0 Number of bytes successfully written to the TLS connection.
|
||||
* @retval <=0 Failed to write bytes to the TLS connection.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_ssl_write(SSL *ssl,
|
||||
const void *buf,
|
||||
int num){
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_ssl_write_ctr)){
|
||||
return -1;
|
||||
}
|
||||
return SSL_write(ssl, buf, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when sprintf() fails.
|
||||
*
|
||||
* @param[in] s Buffer to store the output contents to.
|
||||
* @param[in] format Format string defined in sprintf().
|
||||
* @retval >=0 Number of bytes copied to @p s, excluding the null-terminator.
|
||||
* @retval <0 Output or formatting error.
|
||||
*/
|
||||
int
|
||||
smtp_test_seam_sprintf(char *s,
|
||||
const char *format, ...){
|
||||
va_list ap;
|
||||
int rc;
|
||||
|
||||
if(smtp_test_seam_dec_err_ctr(&g_smtp_test_err_sprintf_ctr)){
|
||||
errno = ENOMEM;
|
||||
return g_smtp_test_err_sprintf_rc;
|
||||
}
|
||||
va_start(ap, format);
|
||||
rc = vsprintf(s, format, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control the return value of strlen().
|
||||
*
|
||||
* @param[in] s Null-terminated string.
|
||||
* @return Length of @p s.
|
||||
*/
|
||||
size_t
|
||||
smtp_test_seam_strlen(const char *s){
|
||||
size_t result;
|
||||
|
||||
if(g_smtp_test_strlen_custom_ret){
|
||||
result = g_smtp_test_strlen_ret_value;
|
||||
}
|
||||
else{
|
||||
result = strlen(s);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the test harness to control when time() fails.
|
||||
*
|
||||
* @param[out] tloc Buffer to hold the time_t results.
|
||||
* @retval >=0 Time in seconds since the Epoch.
|
||||
* @retval -1 Failed to store the time in @p tloc.
|
||||
*/
|
||||
time_t
|
||||
smtp_test_seam_time(time_t *tloc){
|
||||
if(g_smtp_test_time_custom_ret){
|
||||
return g_smtp_test_time_ret_value;
|
||||
}
|
||||
return time(tloc);
|
||||
}
|
||||
|
||||
284
src/tools/web_api/dep/smtp-client/test/seams.h
Normal file
284
src/tools/web_api/dep/smtp-client/test/seams.h
Normal file
@@ -0,0 +1,284 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Test seams for the smtp-client library.
|
||||
* @author James Humphrey (mail@somnisoft.com)
|
||||
* @version 1.00
|
||||
*
|
||||
* Used by the smtp-client testing framework to inject specific return values
|
||||
* by some standard library functions. This makes it possible to test less
|
||||
* common errors like out of memory conditions and input/output errors.
|
||||
*
|
||||
* This software has been placed into the public domain using CC0.
|
||||
*/
|
||||
#ifndef SMTP_TEST_SEAMS_H
|
||||
#define SMTP_TEST_SEAMS_H
|
||||
|
||||
#include "test.h"
|
||||
|
||||
/*
|
||||
* Redefine these functions to internal test seam functions.
|
||||
*/
|
||||
#undef BIO_new_socket
|
||||
#undef BIO_should_retry
|
||||
#undef calloc
|
||||
#undef close
|
||||
#undef connect
|
||||
#undef ERR_peek_error
|
||||
#undef fclose
|
||||
#undef ferror
|
||||
#undef gmtime_r
|
||||
#undef HMAC
|
||||
#undef localtime_r
|
||||
#undef malloc
|
||||
#undef mktime
|
||||
#undef realloc
|
||||
#undef recv
|
||||
#undef select
|
||||
#undef send
|
||||
#undef socket
|
||||
#undef SSL_connect
|
||||
#undef SSL_CTX_new
|
||||
#undef SSL_do_handshake
|
||||
#undef SSL_get_peer_certificate
|
||||
#undef X509_check_host
|
||||
#undef SSL_new
|
||||
#undef SSL_read
|
||||
#undef SSL_write
|
||||
#undef sprintf
|
||||
#undef strlen
|
||||
#undef time
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_bio_new_socket.
|
||||
*/
|
||||
#define BIO_new_socket smtp_test_seam_bio_new_socket
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_bio_should_retry.
|
||||
*/
|
||||
#define BIO_should_retry smtp_test_seam_bio_should_retry
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_calloc.
|
||||
*/
|
||||
#define calloc smtp_test_seam_calloc
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_close.
|
||||
*/
|
||||
#define close smtp_test_seam_close
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_connect.
|
||||
*/
|
||||
#define connect smtp_test_seam_connect
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_err_peek_error.
|
||||
*/
|
||||
#define ERR_peek_error smtp_test_seam_err_peek_error
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_fclose.
|
||||
*/
|
||||
#define fclose smtp_test_seam_fclose
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_ferror.
|
||||
*/
|
||||
#define ferror smtp_test_seam_ferror
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_gmtime_r.
|
||||
*/
|
||||
#define gmtime_r smtp_test_seam_gmtime_r
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_hmac.
|
||||
*/
|
||||
#define HMAC smtp_test_seam_hmac
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_localtime_r.
|
||||
*/
|
||||
#define localtime_r smtp_test_seam_localtime_r
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_malloc.
|
||||
*/
|
||||
#define malloc smtp_test_seam_malloc
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_mktime.
|
||||
*/
|
||||
#define mktime smtp_test_seam_mktime
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_realloc.
|
||||
*/
|
||||
#define realloc smtp_test_seam_realloc
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_recv.
|
||||
*/
|
||||
#define recv smtp_test_seam_recv
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_select.
|
||||
*/
|
||||
#define select smtp_test_seam_select
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_send.
|
||||
*/
|
||||
#define send smtp_test_seam_send
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_socket.
|
||||
*/
|
||||
#define socket smtp_test_seam_socket
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_ssl_connect.
|
||||
*/
|
||||
#define SSL_connect smtp_test_seam_ssl_connect
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_ssl_ctx_new.
|
||||
*/
|
||||
#define SSL_CTX_new smtp_test_seam_ssl_ctx_new
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_ssl_do_handshake.
|
||||
*/
|
||||
#define SSL_do_handshake smtp_test_seam_ssl_do_handshake
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_ssl_get_peer_certificate.
|
||||
*/
|
||||
#define SSL_get_peer_certificate smtp_test_seam_ssl_get_peer_certificate
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_x509_check_host.
|
||||
*/
|
||||
#define X509_check_host smtp_test_seam_x509_check_host
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_ssl_new.
|
||||
*/
|
||||
#define SSL_new smtp_test_seam_ssl_new
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_ssl_read.
|
||||
*/
|
||||
#define SSL_read smtp_test_seam_ssl_read
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_ssl_write.
|
||||
*/
|
||||
#define SSL_write smtp_test_seam_ssl_write
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_sprintf.
|
||||
*/
|
||||
#define sprintf smtp_test_seam_sprintf
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control the return value of this function.
|
||||
*
|
||||
* See @ref smtp_test_seam_strlen.
|
||||
*/
|
||||
#define strlen smtp_test_seam_strlen
|
||||
|
||||
/**
|
||||
* Redefine this function from smtp.c and inject a test seam which
|
||||
* can control when this function fails.
|
||||
*
|
||||
* See @ref smtp_test_seam_time.
|
||||
*/
|
||||
#define time smtp_test_seam_time
|
||||
|
||||
#endif
|
||||
|
||||
4968
src/tools/web_api/dep/smtp-client/test/test.c
Normal file
4968
src/tools/web_api/dep/smtp-client/test/test.c
Normal file
File diff suppressed because it is too large
Load Diff
577
src/tools/web_api/dep/smtp-client/test/test.h
Normal file
577
src/tools/web_api/dep/smtp-client/test/test.h
Normal file
@@ -0,0 +1,577 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Test the smtp-client library.
|
||||
* @author James Humphrey (mail@somnisoft.com)
|
||||
* @version 1.00
|
||||
*
|
||||
* This smtp-client testing framework has 100% branch coverage on POSIX
|
||||
* systems. It requires a Postfix SMTP server that supports all of the
|
||||
* connection security and authentication methods. These functional tests
|
||||
* also require the user to manually check and ensure that the destination
|
||||
* addresses received all of the test emails.
|
||||
*
|
||||
* This software has been placed into the public domain using CC0.
|
||||
*
|
||||
* @section test_seams_countdown_global
|
||||
*
|
||||
* The test harnesses control most of the test seams through the use of
|
||||
* global counter values.
|
||||
*
|
||||
* Setting a global counter to -1 will make the test seam function operate
|
||||
* as it normally would. If set to a positive value, the value will continue
|
||||
* to decrement every time the function gets called. When the counter reaches
|
||||
* 0, the test seam will force the function to return an error value.
|
||||
*
|
||||
* For example, initially setting the counter to 0 will force the test seam
|
||||
* to return an error condition the first time it gets called. Setting the
|
||||
* value to 1 initially will force the test seam to return an error condition
|
||||
* on the second time it gets called.
|
||||
*/
|
||||
#ifndef SMTP_TEST_H
|
||||
#define SMTP_TEST_H
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "../src/smtp.h"
|
||||
|
||||
#ifdef SMTP_OPENSSL
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/x509v3.h>
|
||||
#endif /* SMTP_OPENSSL */
|
||||
|
||||
struct smtp_command;
|
||||
struct str_getdelimfd;
|
||||
|
||||
int
|
||||
smtp_si_add_size_t(const size_t a,
|
||||
const size_t b,
|
||||
size_t *const result);
|
||||
|
||||
int
|
||||
smtp_si_sub_size_t(const size_t a,
|
||||
const size_t b,
|
||||
size_t *const result);
|
||||
|
||||
int
|
||||
smtp_si_mul_size_t(const size_t a,
|
||||
const size_t b,
|
||||
size_t *const result);
|
||||
|
||||
size_t
|
||||
smtp_base64_decode(const char *const buf,
|
||||
unsigned char **decode);
|
||||
|
||||
char *
|
||||
smtp_base64_encode(const char *const buf,
|
||||
size_t buflen);
|
||||
|
||||
char *
|
||||
smtp_bin2hex(const unsigned char *const s,
|
||||
size_t slen);
|
||||
|
||||
enum smtp_status_code
|
||||
smtp_write(struct smtp *const smtp,
|
||||
const char *const buf,
|
||||
size_t len);
|
||||
|
||||
int
|
||||
smtp_str_getdelimfd(struct str_getdelimfd *const gdfd);
|
||||
|
||||
int
|
||||
smtp_str_getdelimfd_set_line_and_buf(struct str_getdelimfd *const gdfd,
|
||||
size_t copy_len);
|
||||
|
||||
void
|
||||
smtp_str_getdelimfd_free(struct str_getdelimfd *const gdfd);
|
||||
|
||||
char *
|
||||
smtp_stpcpy(char *s1,
|
||||
const char *s2);
|
||||
|
||||
void *
|
||||
smtp_reallocarray(void *ptr,
|
||||
size_t nmemb,
|
||||
size_t size);
|
||||
|
||||
char *
|
||||
smtp_strdup(const char *s);
|
||||
|
||||
char *
|
||||
smtp_str_replace(const char *const search,
|
||||
const char *const replace,
|
||||
const char *const s);
|
||||
|
||||
size_t
|
||||
smtp_utf8_charlen(char c);
|
||||
|
||||
int
|
||||
smtp_str_has_nonascii_utf8(const char *const s);
|
||||
|
||||
size_t
|
||||
smtp_strnlen_utf8(const char *s,
|
||||
size_t maxlen);
|
||||
|
||||
size_t
|
||||
smtp_fold_whitespace_get_offset(const char *const s,
|
||||
unsigned int maxlen);
|
||||
|
||||
char *
|
||||
smtp_fold_whitespace(const char *const s,
|
||||
unsigned int maxlen);
|
||||
|
||||
char *
|
||||
smtp_chunk_split(const char *const s,
|
||||
size_t chunklen,
|
||||
const char *const end);
|
||||
|
||||
char *
|
||||
smtp_ffile_get_contents(FILE *stream,
|
||||
size_t *bytes_read);
|
||||
|
||||
char *
|
||||
smtp_file_get_contents(const char *const filename,
|
||||
size_t *bytes_read);
|
||||
|
||||
int
|
||||
smtp_parse_cmd_line(char *const line,
|
||||
struct smtp_command *const cmd);
|
||||
|
||||
int
|
||||
smtp_date_rfc_2822(char *const date);
|
||||
|
||||
int
|
||||
smtp_address_validate_email(const char *const email);
|
||||
|
||||
int
|
||||
smtp_address_validate_name(const char *const name);
|
||||
|
||||
int
|
||||
smtp_attachment_validate_name(const char *const name);
|
||||
|
||||
int
|
||||
smtp_header_key_validate(const char *const key);
|
||||
|
||||
int
|
||||
smtp_header_value_validate(const char *const value);
|
||||
|
||||
/* test seams */
|
||||
int
|
||||
smtp_test_seam_dec_err_ctr(int *const test_err_ctr);
|
||||
|
||||
BIO *
|
||||
smtp_test_seam_bio_new_socket(int sock,
|
||||
int close_flag);
|
||||
|
||||
int
|
||||
smtp_test_seam_bio_should_retry(BIO *bio);
|
||||
|
||||
void *
|
||||
smtp_test_seam_calloc(size_t nelem,
|
||||
size_t elsize);
|
||||
|
||||
int
|
||||
smtp_test_seam_close(int fildes);
|
||||
|
||||
int
|
||||
smtp_test_seam_connect(int socket,
|
||||
const struct sockaddr *address,
|
||||
socklen_t address_len);
|
||||
|
||||
unsigned long
|
||||
smtp_test_seam_err_peek_error(void);
|
||||
|
||||
int
|
||||
smtp_test_seam_fclose(FILE *stream);
|
||||
|
||||
int
|
||||
smtp_test_seam_ferror(FILE *stream);
|
||||
|
||||
struct tm *
|
||||
smtp_test_seam_gmtime_r(const time_t *timep,
|
||||
struct tm *result);
|
||||
|
||||
unsigned char *
|
||||
smtp_test_seam_hmac(const EVP_MD *evp_md,
|
||||
const void *key,
|
||||
int key_len,
|
||||
const unsigned char *d,
|
||||
size_t n,
|
||||
unsigned char *md,
|
||||
unsigned int *md_len);
|
||||
|
||||
struct tm *
|
||||
smtp_test_seam_localtime_r(const time_t *timep,
|
||||
struct tm *result);
|
||||
|
||||
void *
|
||||
smtp_test_seam_malloc(size_t size);
|
||||
|
||||
time_t
|
||||
smtp_test_seam_mktime(struct tm *timeptr);
|
||||
|
||||
|
||||
void *
|
||||
smtp_test_seam_realloc(void *ptr,
|
||||
size_t size);
|
||||
|
||||
long
|
||||
smtp_test_seam_recv(int socket,
|
||||
void *buffer,
|
||||
size_t length,
|
||||
int flags);
|
||||
|
||||
int
|
||||
smtp_test_seam_select(int nfds,
|
||||
fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
fd_set *errorfds,
|
||||
struct timeval *timeout);
|
||||
|
||||
ssize_t
|
||||
smtp_test_seam_send(int socket,
|
||||
const void *buffer,
|
||||
size_t length,
|
||||
int flags);
|
||||
|
||||
int
|
||||
smtp_test_seam_socket(int domain,
|
||||
int type,
|
||||
int protocol);
|
||||
|
||||
int
|
||||
smtp_test_seam_ssl_connect(SSL *ssl);
|
||||
|
||||
SSL_CTX *
|
||||
smtp_test_seam_ssl_ctx_new(const SSL_METHOD *method);
|
||||
|
||||
int
|
||||
smtp_test_seam_ssl_do_handshake(SSL *ssl);
|
||||
|
||||
X509 *
|
||||
smtp_test_seam_ssl_get_peer_certificate(const SSL *ssl);
|
||||
|
||||
int
|
||||
smtp_test_seam_x509_check_host(X509 *cert,
|
||||
const char *name,
|
||||
size_t namelen,
|
||||
unsigned int flags,
|
||||
char **peername);
|
||||
|
||||
SSL *
|
||||
smtp_test_seam_ssl_new(SSL_CTX *ctx);
|
||||
|
||||
int
|
||||
smtp_test_seam_ssl_read(SSL *ssl,
|
||||
void *buf,
|
||||
int num);
|
||||
|
||||
int
|
||||
smtp_test_seam_ssl_write(SSL *ssl,
|
||||
const void *buf,
|
||||
int num);
|
||||
|
||||
int
|
||||
smtp_test_seam_sprintf(char *s,
|
||||
const char *format, ...);
|
||||
|
||||
size_t
|
||||
smtp_test_seam_strlen(const char *s);
|
||||
|
||||
time_t
|
||||
smtp_test_seam_time(time_t *tloc);
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_bio_new_socket.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_bio_new_socket_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_bio_should_retry.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_bio_should_retry_ctr;
|
||||
|
||||
/**
|
||||
* Value to force the BIO_should_retry() function to return.
|
||||
*
|
||||
* This value will only get returned if
|
||||
* @ref g_smtp_test_err_bio_should_retry_ctr
|
||||
* has a value of 0 and this does not have a value of -1.
|
||||
*/
|
||||
extern int g_smtp_test_err_bio_should_retry_rc;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_calloc.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_calloc_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_close.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_close_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_connect.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_connect_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_err_peek_error.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_err_peek_error_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_fclose.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_fclose_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_ferror.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_ferror_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_gmtime_r.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_gmtime_r_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_hmac.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_hmac_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_localtime_r.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_localtime_r_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_malloc.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_malloc_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_mktime.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_mktime_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_realloc.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_realloc_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_recv.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_recv_ctr;
|
||||
|
||||
/**
|
||||
* Value to force the recv() function to return.
|
||||
*
|
||||
* This value will only get returned if
|
||||
* @ref g_smtp_test_err_recv_ctr
|
||||
* has a value of 0 and this does not have a value of -1.
|
||||
*/
|
||||
extern int g_smtp_test_err_recv_rc;
|
||||
|
||||
/**
|
||||
* Set the received bytes in recv() and SSL_read() to this value if it
|
||||
* contains a null-terminated string at least one bytes long.
|
||||
*
|
||||
* This makes it easier to inject a bad server response for testing the
|
||||
* smtp-client handling of those bad responses.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern char g_smtp_test_err_recv_bytes[90];
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_select.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_select_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_send.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_send_ctr;
|
||||
|
||||
/**
|
||||
* Indicate if we should only send one byte at a time.
|
||||
*/
|
||||
extern int g_smtp_test_send_one_byte;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_si_add_size_t.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_si_add_size_t_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_si_sub_size_t.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_si_sub_size_t_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_si_mul_size_t.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_si_mul_size_t_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_socket.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_socket_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_ssl_connect.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_ssl_connect_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_ssl_ctx_new.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_ssl_ctx_new_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_ssl_do_handshake.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_ssl_do_handshake_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_ssl_get_peer_certificate.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_ssl_get_peer_certificate_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_x509_check_host.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_x509_check_host_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_ssl_new.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_ssl_new_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_ssl_read.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_ssl_read_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_ssl_write.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_ssl_write_ctr;
|
||||
|
||||
/**
|
||||
* Counter for @ref smtp_test_seam_sprintf.
|
||||
*
|
||||
* See @ref test_seams_countdown_global for more details.
|
||||
*/
|
||||
extern int g_smtp_test_err_sprintf_ctr;
|
||||
|
||||
/**
|
||||
* Value to force the sprintf() function to return.
|
||||
*
|
||||
* This value will only get returned if @ref g_smtp_test_err_sprintf_ctr has
|
||||
* a value of 0.
|
||||
*/
|
||||
extern int g_smtp_test_err_sprintf_rc;
|
||||
|
||||
/**
|
||||
* Indicates if the strlen() function should return a test value.
|
||||
*
|
||||
* This can get set to one of two values:
|
||||
* - 0 - The strlen() function will operate normally.
|
||||
* - !0 - The strlen() function will return the value specified in
|
||||
* @ref g_smtp_test_strlen_ret_value.
|
||||
*/
|
||||
extern int g_smtp_test_strlen_custom_ret;
|
||||
|
||||
/**
|
||||
* Value to force the strlen() function to return.
|
||||
*
|
||||
* This value will only get returned if @ref g_smtp_test_strlen_custom_ret
|
||||
* has been set.
|
||||
*/
|
||||
extern size_t g_smtp_test_strlen_ret_value;
|
||||
|
||||
/**
|
||||
* Indicates if the time() function should return a custom value.
|
||||
*
|
||||
* This can get set to one of two values:
|
||||
* - 0 - The time() function will operate normally.
|
||||
* - !0 - The time() function will return the value specified in
|
||||
* @ref g_smtp_test_time_ret_value.
|
||||
*/
|
||||
extern int g_smtp_test_time_custom_ret;
|
||||
|
||||
/**
|
||||
* Value to force the time() function to return.
|
||||
*
|
||||
* This value will only get returned if @ref g_smtp_test_time_custom_ret has
|
||||
* a positive value.
|
||||
*/
|
||||
extern time_t g_smtp_test_time_ret_value;
|
||||
|
||||
#endif /* SMTP_TEST_H */
|
||||
|
||||
BIN
src/tools/web_api/dep/smtp-client/test/test.pdf
Normal file
BIN
src/tools/web_api/dep/smtp-client/test/test.pdf
Normal file
Binary file not shown.
49
src/tools/web_api/dep/smtp-client/test/test_cpp_wrapper.cpp
Normal file
49
src/tools/web_api/dep/smtp-client/test/test_cpp_wrapper.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Test the smtp-client CPP wrapper.
|
||||
* @author James Humphrey (mail@somnisoft.com)
|
||||
* @version 1.00
|
||||
*
|
||||
* Example program demonstrating how to use the CPP wrapper class.
|
||||
*
|
||||
* This software has been placed into the public domain using CC0.
|
||||
*/
|
||||
#include <err.h>
|
||||
|
||||
#include <SMTPMail.h>
|
||||
|
||||
/**
|
||||
* Main program entry point for the example smtp-client CPP class wrapper.
|
||||
*
|
||||
* @param[in] argc Number of arguments in @p argv.
|
||||
* @param[in] argv String array containing the program name and any optional
|
||||
* parameters described above.
|
||||
* @retval 0 Email has been sent.
|
||||
* @retval 1 An error occurred while sending email. Although unlikely, an email
|
||||
* can still get sent even after returning with this error code.
|
||||
*/
|
||||
int main(int argc, char *argv[]){
|
||||
SMTPMail *mail;
|
||||
|
||||
mail = new SMTPMail();
|
||||
try{
|
||||
mail->open("localhost", "25", SMTP_SECURITY_NONE, SMTP_DEBUG, NULL);
|
||||
mail->auth(SMTP_AUTH_NONE, NULL, NULL);
|
||||
mail->address_add(SMTP_ADDRESS_FROM,
|
||||
"mail@somnisoft.com",
|
||||
"From Address");
|
||||
mail->address_add(SMTP_ADDRESS_TO,
|
||||
"mail@somnisoft.com",
|
||||
"To Address");
|
||||
mail->header_add("Subject", "Test email (SMTPMail)");
|
||||
mail->mail("Email sent using CPP SMTPMail class");
|
||||
mail->close();
|
||||
}
|
||||
catch(SMTPMailException sme){
|
||||
errx(1, "Failed to send email: %s\n", sme.what());
|
||||
}
|
||||
delete mail;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
102
src/tools/web_api/dep/smtp-client/test/test_nossl.c
Normal file
102
src/tools/web_api/dep/smtp-client/test/test_nossl.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Test the smtp-client library without OpenSSL.
|
||||
* @author James Humphrey (mail@somnisoft.com)
|
||||
* @version 1.00
|
||||
*
|
||||
* These functional tests ensure that the smtp-client library works when
|
||||
* configured without OpenSSL.
|
||||
*
|
||||
* This software has been placed into the public domain using CC0.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <smtp.h>
|
||||
|
||||
/**
|
||||
* Load the test email to send from a configuration file.
|
||||
*
|
||||
* @param[out] email String buffer to store the email in.
|
||||
* @param[in] emailsz Number of bytes in email.
|
||||
*/
|
||||
static void
|
||||
load_test_email(char *const email,
|
||||
size_t emailsz){
|
||||
FILE *fp;
|
||||
int rc;
|
||||
size_t bytes_read;
|
||||
|
||||
fp = fopen("test/config/test_email.txt", "r");
|
||||
assert(fp);
|
||||
|
||||
bytes_read = fread(email, sizeof(*email), emailsz, fp);
|
||||
assert(bytes_read > 0);
|
||||
|
||||
email[bytes_read - 1] = '\0';
|
||||
|
||||
rc = ferror(fp);
|
||||
assert(rc == 0);
|
||||
|
||||
rc = fclose(fp);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the configuration file and send a single test email.
|
||||
*/
|
||||
static void
|
||||
test_nossl_smtp(void){
|
||||
int rc;
|
||||
struct smtp *smtp;
|
||||
char email[1000];
|
||||
|
||||
load_test_email(email, sizeof(email));
|
||||
|
||||
rc = smtp_open("localhost",
|
||||
"25",
|
||||
SMTP_SECURITY_NONE,
|
||||
SMTP_DEBUG,
|
||||
NULL,
|
||||
&smtp);
|
||||
assert(rc == SMTP_STATUS_OK);
|
||||
|
||||
rc = smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_FROM,
|
||||
email,
|
||||
"Test Email");
|
||||
assert(rc == SMTP_STATUS_OK);
|
||||
|
||||
rc = smtp_address_add(smtp,
|
||||
SMTP_ADDRESS_TO,
|
||||
email,
|
||||
"Test Email");
|
||||
assert(rc == SMTP_STATUS_OK);
|
||||
|
||||
rc = smtp_header_add(smtp,
|
||||
"Subject",
|
||||
"SMTP Test: Build Without OpenSSL");
|
||||
assert(rc == SMTP_STATUS_OK);
|
||||
|
||||
rc = smtp_mail(smtp,
|
||||
"This email tests the build without OpenSSL compiled into"
|
||||
" the library.");
|
||||
assert(rc == SMTP_STATUS_OK);
|
||||
|
||||
rc = smtp_close(smtp);
|
||||
assert(rc == SMTP_STATUS_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main program entry point for testing the smtp-client library
|
||||
* build without OpenSSL.
|
||||
*
|
||||
* @retval 0 All tests passed.
|
||||
* @retval 1 Error.
|
||||
*/
|
||||
int main(void){
|
||||
test_nossl_smtp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
OpenSSL malloc
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:CRYPTO_malloc
|
||||
...
|
||||
obj:*libcrypto*
|
||||
}
|
||||
{
|
||||
OpenSSL zalloc
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:CRYPTO_zalloc
|
||||
...
|
||||
obj:*libcrypto*
|
||||
}
|
||||
{
|
||||
OpenSSL realloc
|
||||
Memcheck:Leak
|
||||
fun:realloc
|
||||
fun:CRYPTO_realloc
|
||||
...
|
||||
obj:*libcrypto*
|
||||
}
|
||||
35
src/tools/web_api/dep/tweetnacl/nacl.h
Normal file
35
src/tools/web_api/dep/tweetnacl/nacl.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef NACL_H
|
||||
#define NACL_H
|
||||
|
||||
#include <random>
|
||||
|
||||
extern "C" {
|
||||
// for tweetnacl
|
||||
#include "tweetnacl.h"
|
||||
|
||||
void randombytes(unsigned char* x, unsigned long long xlen)
|
||||
{
|
||||
std::random_device rd;
|
||||
std::uniform_int_distribution<unsigned int> dist(
|
||||
std::numeric_limits<unsigned int>::min(),
|
||||
std::numeric_limits<unsigned int>::max());
|
||||
|
||||
while (xlen > 0)
|
||||
{
|
||||
unsigned int number = dist(rd);
|
||||
for (size_t i = sizeof(unsigned int); i > 0 ; i--)
|
||||
{
|
||||
unsigned char byteValue = (number >> (i - 1) * 8) & 0xFF;
|
||||
*x = byteValue;
|
||||
|
||||
x += 1;
|
||||
xlen -= 1;
|
||||
|
||||
if (xlen <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
809
src/tools/web_api/dep/tweetnacl/tweetnacl.c
Normal file
809
src/tools/web_api/dep/tweetnacl/tweetnacl.c
Normal file
@@ -0,0 +1,809 @@
|
||||
#include "tweetnacl.h"
|
||||
#define FOR(i,n) for (i = 0;i < n;++i)
|
||||
#define sv static void
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned long u32;
|
||||
typedef unsigned long long u64;
|
||||
typedef long long i64;
|
||||
typedef i64 gf[16];
|
||||
extern void randombytes(u8 *,u64);
|
||||
|
||||
static const u8
|
||||
_0[16],
|
||||
_9[32] = {9};
|
||||
static const gf
|
||||
gf0,
|
||||
gf1 = {1},
|
||||
_121665 = {0xDB41,1},
|
||||
D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
|
||||
D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
|
||||
X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
|
||||
Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
|
||||
I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
|
||||
|
||||
static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
|
||||
|
||||
static u32 ld32(const u8 *x)
|
||||
{
|
||||
u32 u = x[3];
|
||||
u = (u<<8)|x[2];
|
||||
u = (u<<8)|x[1];
|
||||
return (u<<8)|x[0];
|
||||
}
|
||||
|
||||
static u64 dl64(const u8 *x)
|
||||
{
|
||||
u64 i,u=0;
|
||||
FOR(i,8) u=(u<<8)|x[i];
|
||||
return u;
|
||||
}
|
||||
|
||||
sv st32(u8 *x,u32 u)
|
||||
{
|
||||
int i;
|
||||
FOR(i,4) { x[i] = u; u >>= 8; }
|
||||
}
|
||||
|
||||
sv ts64(u8 *x,u64 u)
|
||||
{
|
||||
int i;
|
||||
for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
|
||||
}
|
||||
|
||||
static int vn(const u8 *x,const u8 *y,int n)
|
||||
{
|
||||
u32 i,d = 0;
|
||||
FOR(i,n) d |= x[i]^y[i];
|
||||
return (1 & ((d - 1) >> 8)) - 1;
|
||||
}
|
||||
|
||||
int crypto_verify_16(const u8 *x,const u8 *y)
|
||||
{
|
||||
return vn(x,y,16);
|
||||
}
|
||||
|
||||
int crypto_verify_32(const u8 *x,const u8 *y)
|
||||
{
|
||||
return vn(x,y,32);
|
||||
}
|
||||
|
||||
sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h)
|
||||
{
|
||||
u32 w[16],x[16],y[16],t[4];
|
||||
int i,j,m;
|
||||
|
||||
FOR(i,4) {
|
||||
x[5*i] = ld32(c+4*i);
|
||||
x[1+i] = ld32(k+4*i);
|
||||
x[6+i] = ld32(in+4*i);
|
||||
x[11+i] = ld32(k+16+4*i);
|
||||
}
|
||||
|
||||
FOR(i,16) y[i] = x[i];
|
||||
|
||||
FOR(i,20) {
|
||||
FOR(j,4) {
|
||||
FOR(m,4) t[m] = x[(5*j+4*m)%16];
|
||||
t[1] ^= L32(t[0]+t[3], 7);
|
||||
t[2] ^= L32(t[1]+t[0], 9);
|
||||
t[3] ^= L32(t[2]+t[1],13);
|
||||
t[0] ^= L32(t[3]+t[2],18);
|
||||
FOR(m,4) w[4*j+(j+m)%4] = t[m];
|
||||
}
|
||||
FOR(m,16) x[m] = w[m];
|
||||
}
|
||||
|
||||
if (h) {
|
||||
FOR(i,16) x[i] += y[i];
|
||||
FOR(i,4) {
|
||||
x[5*i] -= ld32(c+4*i);
|
||||
x[6+i] -= ld32(in+4*i);
|
||||
}
|
||||
FOR(i,4) {
|
||||
st32(out+4*i,x[5*i]);
|
||||
st32(out+16+4*i,x[6+i]);
|
||||
}
|
||||
} else
|
||||
FOR(i,16) st32(out + 4 * i,x[i] + y[i]);
|
||||
}
|
||||
|
||||
int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
|
||||
{
|
||||
core(out,in,k,c,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
|
||||
{
|
||||
core(out,in,k,c,1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const u8 sigma[16] = "expand 32-byte k";
|
||||
|
||||
int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k)
|
||||
{
|
||||
u8 z[16],x[64];
|
||||
u32 u,i;
|
||||
if (!b) return 0;
|
||||
FOR(i,16) z[i] = 0;
|
||||
FOR(i,8) z[i] = n[i];
|
||||
while (b >= 64) {
|
||||
crypto_core_salsa20(x,z,k,sigma);
|
||||
FOR(i,64) c[i] = (m?m[i]:0) ^ x[i];
|
||||
u = 1;
|
||||
for (i = 8;i < 16;++i) {
|
||||
u += (u32) z[i];
|
||||
z[i] = u;
|
||||
u >>= 8;
|
||||
}
|
||||
b -= 64;
|
||||
c += 64;
|
||||
if (m) m += 64;
|
||||
}
|
||||
if (b) {
|
||||
crypto_core_salsa20(x,z,k,sigma);
|
||||
FOR(i,b) c[i] = (m?m[i]:0) ^ x[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
return crypto_stream_salsa20_xor(c,0,d,n,k);
|
||||
}
|
||||
|
||||
int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
u8 s[32];
|
||||
crypto_core_hsalsa20(s,n,k,sigma);
|
||||
return crypto_stream_salsa20(c,d,n+16,s);
|
||||
}
|
||||
|
||||
int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
u8 s[32];
|
||||
crypto_core_hsalsa20(s,n,k,sigma);
|
||||
return crypto_stream_salsa20_xor(c,m,d,n+16,s);
|
||||
}
|
||||
|
||||
sv add1305(u32 *h,const u32 *c)
|
||||
{
|
||||
u32 j,u = 0;
|
||||
FOR(j,17) {
|
||||
u += h[j] + c[j];
|
||||
h[j] = u & 255;
|
||||
u >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
static const u32 minusp[17] = {
|
||||
5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
|
||||
} ;
|
||||
|
||||
int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k)
|
||||
{
|
||||
u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17];
|
||||
|
||||
FOR(j,17) r[j]=h[j]=0;
|
||||
FOR(j,16) r[j]=k[j];
|
||||
r[3]&=15;
|
||||
r[4]&=252;
|
||||
r[7]&=15;
|
||||
r[8]&=252;
|
||||
r[11]&=15;
|
||||
r[12]&=252;
|
||||
r[15]&=15;
|
||||
|
||||
while (n > 0) {
|
||||
FOR(j,17) c[j] = 0;
|
||||
for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
|
||||
c[j] = 1;
|
||||
m += j; n -= j;
|
||||
add1305(h,c);
|
||||
FOR(i,17) {
|
||||
x[i] = 0;
|
||||
FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
|
||||
}
|
||||
FOR(i,17) h[i] = x[i];
|
||||
u = 0;
|
||||
FOR(j,16) {
|
||||
u += h[j];
|
||||
h[j] = u & 255;
|
||||
u >>= 8;
|
||||
}
|
||||
u += h[16]; h[16] = u & 3;
|
||||
u = 5 * (u >> 2);
|
||||
FOR(j,16) {
|
||||
u += h[j];
|
||||
h[j] = u & 255;
|
||||
u >>= 8;
|
||||
}
|
||||
u += h[16]; h[16] = u;
|
||||
}
|
||||
|
||||
FOR(j,17) g[j] = h[j];
|
||||
add1305(h,minusp);
|
||||
s = -(h[16] >> 7);
|
||||
FOR(j,17) h[j] ^= s & (g[j] ^ h[j]);
|
||||
|
||||
FOR(j,16) c[j] = k[j + 16];
|
||||
c[16] = 0;
|
||||
add1305(h,c);
|
||||
FOR(j,16) out[j] = h[j];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k)
|
||||
{
|
||||
u8 x[16];
|
||||
crypto_onetimeauth(x,m,n,k);
|
||||
return crypto_verify_16(h,x);
|
||||
}
|
||||
|
||||
int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
int i;
|
||||
if (d < 32) return -1;
|
||||
crypto_stream_xor(c,m,d,n,k);
|
||||
crypto_onetimeauth(c + 16,c + 32,d - 32,c);
|
||||
FOR(i,16) c[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
int i;
|
||||
u8 x[32];
|
||||
if (d < 32) return -1;
|
||||
crypto_stream(x,32,n,k);
|
||||
if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1;
|
||||
crypto_stream_xor(m,c,d,n,k);
|
||||
FOR(i,32) m[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sv set25519(gf r, const gf a)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) r[i]=a[i];
|
||||
}
|
||||
|
||||
sv car25519(gf o)
|
||||
{
|
||||
int i;
|
||||
i64 c;
|
||||
FOR(i,16) {
|
||||
o[i]+=(1LL<<16);
|
||||
c=o[i]>>16;
|
||||
o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
|
||||
o[i]-=c<<16;
|
||||
}
|
||||
}
|
||||
|
||||
sv sel25519(gf p,gf q,int b)
|
||||
{
|
||||
i64 t,i,c=~(b-1);
|
||||
FOR(i,16) {
|
||||
t= c&(p[i]^q[i]);
|
||||
p[i]^=t;
|
||||
q[i]^=t;
|
||||
}
|
||||
}
|
||||
|
||||
sv pack25519(u8 *o,const gf n)
|
||||
{
|
||||
int i,j,b;
|
||||
gf m,t;
|
||||
FOR(i,16) t[i]=n[i];
|
||||
car25519(t);
|
||||
car25519(t);
|
||||
car25519(t);
|
||||
FOR(j,2) {
|
||||
m[0]=t[0]-0xffed;
|
||||
for(i=1;i<15;i++) {
|
||||
m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
|
||||
m[i-1]&=0xffff;
|
||||
}
|
||||
m[15]=t[15]-0x7fff-((m[14]>>16)&1);
|
||||
b=(m[15]>>16)&1;
|
||||
m[14]&=0xffff;
|
||||
sel25519(t,m,1-b);
|
||||
}
|
||||
FOR(i,16) {
|
||||
o[2*i]=t[i]&0xff;
|
||||
o[2*i+1]=t[i]>>8;
|
||||
}
|
||||
}
|
||||
|
||||
static int neq25519(const gf a, const gf b)
|
||||
{
|
||||
u8 c[32],d[32];
|
||||
pack25519(c,a);
|
||||
pack25519(d,b);
|
||||
return crypto_verify_32(c,d);
|
||||
}
|
||||
|
||||
static u8 par25519(const gf a)
|
||||
{
|
||||
u8 d[32];
|
||||
pack25519(d,a);
|
||||
return d[0]&1;
|
||||
}
|
||||
|
||||
sv unpack25519(gf o, const u8 *n)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
|
||||
o[15]&=0x7fff;
|
||||
}
|
||||
|
||||
sv A(gf o,const gf a,const gf b)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) o[i]=a[i]+b[i];
|
||||
}
|
||||
|
||||
sv Z(gf o,const gf a,const gf b)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) o[i]=a[i]-b[i];
|
||||
}
|
||||
|
||||
sv M(gf o,const gf a,const gf b)
|
||||
{
|
||||
i64 i,j,t[31];
|
||||
FOR(i,31) t[i]=0;
|
||||
FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
|
||||
FOR(i,15) t[i]+=38*t[i+16];
|
||||
FOR(i,16) o[i]=t[i];
|
||||
car25519(o);
|
||||
car25519(o);
|
||||
}
|
||||
|
||||
sv S(gf o,const gf a)
|
||||
{
|
||||
M(o,a,a);
|
||||
}
|
||||
|
||||
sv inv25519(gf o,const gf i)
|
||||
{
|
||||
gf c;
|
||||
int a;
|
||||
FOR(a,16) c[a]=i[a];
|
||||
for(a=253;a>=0;a--) {
|
||||
S(c,c);
|
||||
if(a!=2&&a!=4) M(c,c,i);
|
||||
}
|
||||
FOR(a,16) o[a]=c[a];
|
||||
}
|
||||
|
||||
sv pow2523(gf o,const gf i)
|
||||
{
|
||||
gf c;
|
||||
int a;
|
||||
FOR(a,16) c[a]=i[a];
|
||||
for(a=250;a>=0;a--) {
|
||||
S(c,c);
|
||||
if(a!=1) M(c,c,i);
|
||||
}
|
||||
FOR(a,16) o[a]=c[a];
|
||||
}
|
||||
|
||||
int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
|
||||
{
|
||||
u8 z[32];
|
||||
i64 x[80],r,i;
|
||||
gf a,b,c,d,e,f;
|
||||
FOR(i,31) z[i]=n[i];
|
||||
z[31]=(n[31]&127)|64;
|
||||
z[0]&=248;
|
||||
unpack25519(x,p);
|
||||
FOR(i,16) {
|
||||
b[i]=x[i];
|
||||
d[i]=a[i]=c[i]=0;
|
||||
}
|
||||
a[0]=d[0]=1;
|
||||
for(i=254;i>=0;--i) {
|
||||
r=(z[i>>3]>>(i&7))&1;
|
||||
sel25519(a,b,r);
|
||||
sel25519(c,d,r);
|
||||
A(e,a,c);
|
||||
Z(a,a,c);
|
||||
A(c,b,d);
|
||||
Z(b,b,d);
|
||||
S(d,e);
|
||||
S(f,a);
|
||||
M(a,c,a);
|
||||
M(c,b,e);
|
||||
A(e,a,c);
|
||||
Z(a,a,c);
|
||||
S(b,a);
|
||||
Z(c,d,f);
|
||||
M(a,c,_121665);
|
||||
A(a,a,d);
|
||||
M(c,c,a);
|
||||
M(a,d,f);
|
||||
M(d,b,x);
|
||||
S(b,e);
|
||||
sel25519(a,b,r);
|
||||
sel25519(c,d,r);
|
||||
}
|
||||
FOR(i,16) {
|
||||
x[i+16]=a[i];
|
||||
x[i+32]=c[i];
|
||||
x[i+48]=b[i];
|
||||
x[i+64]=d[i];
|
||||
}
|
||||
inv25519(x+32,x+32);
|
||||
M(x+16,x+16,x+32);
|
||||
pack25519(q,x+16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_scalarmult_base(u8 *q,const u8 *n)
|
||||
{
|
||||
return crypto_scalarmult(q,n,_9);
|
||||
}
|
||||
|
||||
int crypto_box_keypair(u8 *y,u8 *x)
|
||||
{
|
||||
randombytes(x,32);
|
||||
return crypto_scalarmult_base(y,x);
|
||||
}
|
||||
|
||||
int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x)
|
||||
{
|
||||
u8 s[32];
|
||||
crypto_scalarmult(s,x,y);
|
||||
return crypto_core_hsalsa20(k,_0,s,sigma);
|
||||
}
|
||||
|
||||
int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
return crypto_secretbox(c,m,d,n,k);
|
||||
}
|
||||
|
||||
int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
|
||||
{
|
||||
return crypto_secretbox_open(m,c,d,n,k);
|
||||
}
|
||||
|
||||
int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x)
|
||||
{
|
||||
u8 k[32];
|
||||
crypto_box_beforenm(k,y,x);
|
||||
return crypto_box_afternm(c,m,d,n,k);
|
||||
}
|
||||
|
||||
int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x)
|
||||
{
|
||||
u8 k[32];
|
||||
crypto_box_beforenm(k,y,x);
|
||||
return crypto_box_open_afternm(m,c,d,n,k);
|
||||
}
|
||||
|
||||
static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); }
|
||||
static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); }
|
||||
static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); }
|
||||
static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
|
||||
static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
|
||||
static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
|
||||
static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
|
||||
|
||||
static const u64 K[80] =
|
||||
{
|
||||
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
|
||||
};
|
||||
|
||||
int crypto_hashblocks(u8 *x,const u8 *m,u64 n)
|
||||
{
|
||||
u64 z[8],b[8],a[8],w[16],t;
|
||||
int i,j;
|
||||
|
||||
FOR(i,8) z[i] = a[i] = dl64(x + 8 * i);
|
||||
|
||||
while (n >= 128) {
|
||||
FOR(i,16) w[i] = dl64(m + 8 * i);
|
||||
|
||||
FOR(i,80) {
|
||||
FOR(j,8) b[j] = a[j];
|
||||
t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16];
|
||||
b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]);
|
||||
b[3] += t;
|
||||
FOR(j,8) a[(j+1)%8] = b[j];
|
||||
if (i%16 == 15)
|
||||
FOR(j,16)
|
||||
w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
|
||||
}
|
||||
|
||||
FOR(i,8) { a[i] += z[i]; z[i] = a[i]; }
|
||||
|
||||
m += 128;
|
||||
n -= 128;
|
||||
}
|
||||
|
||||
FOR(i,8) ts64(x+8*i,z[i]);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static const u8 iv[64] = {
|
||||
0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
|
||||
0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
|
||||
0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
|
||||
0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
|
||||
0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
|
||||
0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
|
||||
0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
|
||||
0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
|
||||
} ;
|
||||
|
||||
int crypto_hash(u8 *out,const u8 *m,u64 n)
|
||||
{
|
||||
u8 h[64],x[256];
|
||||
u64 i,b = n;
|
||||
|
||||
FOR(i,64) h[i] = iv[i];
|
||||
|
||||
crypto_hashblocks(h,m,n);
|
||||
m += n;
|
||||
n &= 127;
|
||||
m -= n;
|
||||
|
||||
FOR(i,256) x[i] = 0;
|
||||
FOR(i,n) x[i] = m[i];
|
||||
x[n] = 128;
|
||||
|
||||
n = 256-128*(n<112);
|
||||
x[n-9] = b >> 61;
|
||||
ts64(x+n-8,b<<3);
|
||||
crypto_hashblocks(h,x,n);
|
||||
|
||||
FOR(i,64) out[i] = h[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sv add(gf p[4],gf q[4])
|
||||
{
|
||||
gf a,b,c,d,t,e,f,g,h;
|
||||
|
||||
Z(a, p[1], p[0]);
|
||||
Z(t, q[1], q[0]);
|
||||
M(a, a, t);
|
||||
A(b, p[0], p[1]);
|
||||
A(t, q[0], q[1]);
|
||||
M(b, b, t);
|
||||
M(c, p[3], q[3]);
|
||||
M(c, c, D2);
|
||||
M(d, p[2], q[2]);
|
||||
A(d, d, d);
|
||||
Z(e, b, a);
|
||||
Z(f, d, c);
|
||||
A(g, d, c);
|
||||
A(h, b, a);
|
||||
|
||||
M(p[0], e, f);
|
||||
M(p[1], h, g);
|
||||
M(p[2], g, f);
|
||||
M(p[3], e, h);
|
||||
}
|
||||
|
||||
sv cswap(gf p[4],gf q[4],u8 b)
|
||||
{
|
||||
int i;
|
||||
FOR(i,4)
|
||||
sel25519(p[i],q[i],b);
|
||||
}
|
||||
|
||||
sv pack(u8 *r,gf p[4])
|
||||
{
|
||||
gf tx, ty, zi;
|
||||
inv25519(zi, p[2]);
|
||||
M(tx, p[0], zi);
|
||||
M(ty, p[1], zi);
|
||||
pack25519(r, ty);
|
||||
r[31] ^= par25519(tx) << 7;
|
||||
}
|
||||
|
||||
sv scalarmult(gf p[4],gf q[4],const u8 *s)
|
||||
{
|
||||
int i;
|
||||
set25519(p[0],gf0);
|
||||
set25519(p[1],gf1);
|
||||
set25519(p[2],gf1);
|
||||
set25519(p[3],gf0);
|
||||
for (i = 255;i >= 0;--i) {
|
||||
u8 b = (s[i/8]>>(i&7))&1;
|
||||
cswap(p,q,b);
|
||||
add(q,p);
|
||||
add(p,p);
|
||||
cswap(p,q,b);
|
||||
}
|
||||
}
|
||||
|
||||
sv scalarbase(gf p[4],const u8 *s)
|
||||
{
|
||||
gf q[4];
|
||||
set25519(q[0],X);
|
||||
set25519(q[1],Y);
|
||||
set25519(q[2],gf1);
|
||||
M(q[3],X,Y);
|
||||
scalarmult(p,q,s);
|
||||
}
|
||||
|
||||
int crypto_sign_keypair(u8 *pk, u8 *sk)
|
||||
{
|
||||
u8 d[64];
|
||||
gf p[4];
|
||||
int i;
|
||||
|
||||
randombytes(sk, 32);
|
||||
crypto_hash(d, sk, 32);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
|
||||
scalarbase(p,d);
|
||||
pack(pk,p);
|
||||
|
||||
FOR(i,32) sk[32 + i] = pk[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
|
||||
|
||||
sv modL(u8 *r,i64 x[64])
|
||||
{
|
||||
i64 carry,i,j;
|
||||
for (i = 63;i >= 32;--i) {
|
||||
carry = 0;
|
||||
for (j = i - 32;j < i - 12;++j) {
|
||||
x[j] += carry - 16 * x[i] * L[j - (i - 32)];
|
||||
carry = (x[j] + 128) >> 8;
|
||||
x[j] -= carry << 8;
|
||||
}
|
||||
x[j] += carry;
|
||||
x[i] = 0;
|
||||
}
|
||||
carry = 0;
|
||||
FOR(j,32) {
|
||||
x[j] += carry - (x[31] >> 4) * L[j];
|
||||
carry = x[j] >> 8;
|
||||
x[j] &= 255;
|
||||
}
|
||||
FOR(j,32) x[j] -= carry * L[j];
|
||||
FOR(i,32) {
|
||||
x[i+1] += x[i] >> 8;
|
||||
r[i] = x[i] & 255;
|
||||
}
|
||||
}
|
||||
|
||||
sv reduce(u8 *r)
|
||||
{
|
||||
i64 x[64],i;
|
||||
FOR(i,64) x[i] = (u64) r[i];
|
||||
FOR(i,64) r[i] = 0;
|
||||
modL(r,x);
|
||||
}
|
||||
|
||||
int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk)
|
||||
{
|
||||
u8 d[64],h[64],r[64];
|
||||
i64 i,j,x[64];
|
||||
gf p[4];
|
||||
|
||||
crypto_hash(d, sk, 32);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
|
||||
*smlen = n+64;
|
||||
FOR(i,n) sm[64 + i] = m[i];
|
||||
FOR(i,32) sm[32 + i] = d[32 + i];
|
||||
|
||||
crypto_hash(r, sm+32, n+32);
|
||||
reduce(r);
|
||||
scalarbase(p,r);
|
||||
pack(sm,p);
|
||||
|
||||
FOR(i,32) sm[i+32] = sk[i+32];
|
||||
crypto_hash(h,sm,n + 64);
|
||||
reduce(h);
|
||||
|
||||
FOR(i,64) x[i] = 0;
|
||||
FOR(i,32) x[i] = (u64) r[i];
|
||||
FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
|
||||
modL(sm + 32,x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unpackneg(gf r[4],const u8 p[32])
|
||||
{
|
||||
gf t, chk, num, den, den2, den4, den6;
|
||||
set25519(r[2],gf1);
|
||||
unpack25519(r[1],p);
|
||||
S(num,r[1]);
|
||||
M(den,num,D);
|
||||
Z(num,num,r[2]);
|
||||
A(den,r[2],den);
|
||||
|
||||
S(den2,den);
|
||||
S(den4,den2);
|
||||
M(den6,den4,den2);
|
||||
M(t,den6,num);
|
||||
M(t,t,den);
|
||||
|
||||
pow2523(t,t);
|
||||
M(t,t,num);
|
||||
M(t,t,den);
|
||||
M(t,t,den);
|
||||
M(r[0],t,den);
|
||||
|
||||
S(chk,r[0]);
|
||||
M(chk,chk,den);
|
||||
if (neq25519(chk, num)) M(r[0],r[0],I);
|
||||
|
||||
S(chk,r[0]);
|
||||
M(chk,chk,den);
|
||||
if (neq25519(chk, num)) return -1;
|
||||
|
||||
if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
|
||||
|
||||
M(r[3],r[0],r[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
|
||||
{
|
||||
int i;
|
||||
u8 t[32],h[64];
|
||||
gf p[4],q[4];
|
||||
|
||||
*mlen = -1;
|
||||
if (n < 64) return -1;
|
||||
|
||||
if (unpackneg(q,pk)) return -1;
|
||||
|
||||
FOR(i,n) m[i] = sm[i];
|
||||
FOR(i,32) m[i+32] = pk[i];
|
||||
crypto_hash(h,m,n);
|
||||
reduce(h);
|
||||
scalarmult(p,q,h);
|
||||
|
||||
scalarbase(q,sm + 32);
|
||||
add(p,q);
|
||||
pack(t,p);
|
||||
|
||||
n -= 64;
|
||||
if (crypto_verify_32(sm, t)) {
|
||||
FOR(i,n) m[i] = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FOR(i,n) m[i] = sm[i + 64];
|
||||
*mlen = n;
|
||||
return 0;
|
||||
}
|
||||
272
src/tools/web_api/dep/tweetnacl/tweetnacl.h
Normal file
272
src/tools/web_api/dep/tweetnacl/tweetnacl.h
Normal file
@@ -0,0 +1,272 @@
|
||||
#ifndef TWEETNACL_H
|
||||
#define TWEETNACL_H
|
||||
#define crypto_auth_PRIMITIVE "hmacsha512256"
|
||||
#define crypto_auth crypto_auth_hmacsha512256
|
||||
#define crypto_auth_verify crypto_auth_hmacsha512256_verify
|
||||
#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES
|
||||
#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES
|
||||
#define crypto_auth_IMPLEMENTATION crypto_auth_hmacsha512256_IMPLEMENTATION
|
||||
#define crypto_auth_VERSION crypto_auth_hmacsha512256_VERSION
|
||||
#define crypto_auth_hmacsha512256_tweet_BYTES 32
|
||||
#define crypto_auth_hmacsha512256_tweet_KEYBYTES 32
|
||||
extern int crypto_auth_hmacsha512256_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
#define crypto_auth_hmacsha512256_tweet_VERSION "-"
|
||||
#define crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_tweet
|
||||
#define crypto_auth_hmacsha512256_verify crypto_auth_hmacsha512256_tweet_verify
|
||||
#define crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_tweet_BYTES
|
||||
#define crypto_auth_hmacsha512256_KEYBYTES crypto_auth_hmacsha512256_tweet_KEYBYTES
|
||||
#define crypto_auth_hmacsha512256_VERSION crypto_auth_hmacsha512256_tweet_VERSION
|
||||
#define crypto_auth_hmacsha512256_IMPLEMENTATION "crypto_auth/hmacsha512256/tweet"
|
||||
#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305"
|
||||
#define crypto_box crypto_box_curve25519xsalsa20poly1305
|
||||
#define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open
|
||||
#define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair
|
||||
#define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm
|
||||
#define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm
|
||||
#define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm
|
||||
#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
|
||||
#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
|
||||
#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
|
||||
#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
|
||||
#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
|
||||
#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
|
||||
#define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION
|
||||
#define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 24
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 32
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 16
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(unsigned char *,unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(unsigned char *,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
#define crypto_box_curve25519xsalsa20poly1305_tweet_VERSION "-"
|
||||
#define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet
|
||||
#define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open
|
||||
#define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair
|
||||
#define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm
|
||||
#define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm
|
||||
#define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm
|
||||
#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES
|
||||
#define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_tweet_VERSION
|
||||
#define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/tweet"
|
||||
#define crypto_core_PRIMITIVE "salsa20"
|
||||
#define crypto_core crypto_core_salsa20
|
||||
#define crypto_core_OUTPUTBYTES crypto_core_salsa20_OUTPUTBYTES
|
||||
#define crypto_core_INPUTBYTES crypto_core_salsa20_INPUTBYTES
|
||||
#define crypto_core_KEYBYTES crypto_core_salsa20_KEYBYTES
|
||||
#define crypto_core_CONSTBYTES crypto_core_salsa20_CONSTBYTES
|
||||
#define crypto_core_IMPLEMENTATION crypto_core_salsa20_IMPLEMENTATION
|
||||
#define crypto_core_VERSION crypto_core_salsa20_VERSION
|
||||
#define crypto_core_salsa20_tweet_OUTPUTBYTES 64
|
||||
#define crypto_core_salsa20_tweet_INPUTBYTES 16
|
||||
#define crypto_core_salsa20_tweet_KEYBYTES 32
|
||||
#define crypto_core_salsa20_tweet_CONSTBYTES 16
|
||||
extern int crypto_core_salsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
|
||||
#define crypto_core_salsa20_tweet_VERSION "-"
|
||||
#define crypto_core_salsa20 crypto_core_salsa20_tweet
|
||||
#define crypto_core_salsa20_OUTPUTBYTES crypto_core_salsa20_tweet_OUTPUTBYTES
|
||||
#define crypto_core_salsa20_INPUTBYTES crypto_core_salsa20_tweet_INPUTBYTES
|
||||
#define crypto_core_salsa20_KEYBYTES crypto_core_salsa20_tweet_KEYBYTES
|
||||
#define crypto_core_salsa20_CONSTBYTES crypto_core_salsa20_tweet_CONSTBYTES
|
||||
#define crypto_core_salsa20_VERSION crypto_core_salsa20_tweet_VERSION
|
||||
#define crypto_core_salsa20_IMPLEMENTATION "crypto_core/salsa20/tweet"
|
||||
#define crypto_core_hsalsa20_tweet_OUTPUTBYTES 32
|
||||
#define crypto_core_hsalsa20_tweet_INPUTBYTES 16
|
||||
#define crypto_core_hsalsa20_tweet_KEYBYTES 32
|
||||
#define crypto_core_hsalsa20_tweet_CONSTBYTES 16
|
||||
extern int crypto_core_hsalsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
|
||||
#define crypto_core_hsalsa20_tweet_VERSION "-"
|
||||
#define crypto_core_hsalsa20 crypto_core_hsalsa20_tweet
|
||||
#define crypto_core_hsalsa20_OUTPUTBYTES crypto_core_hsalsa20_tweet_OUTPUTBYTES
|
||||
#define crypto_core_hsalsa20_INPUTBYTES crypto_core_hsalsa20_tweet_INPUTBYTES
|
||||
#define crypto_core_hsalsa20_KEYBYTES crypto_core_hsalsa20_tweet_KEYBYTES
|
||||
#define crypto_core_hsalsa20_CONSTBYTES crypto_core_hsalsa20_tweet_CONSTBYTES
|
||||
#define crypto_core_hsalsa20_VERSION crypto_core_hsalsa20_tweet_VERSION
|
||||
#define crypto_core_hsalsa20_IMPLEMENTATION "crypto_core/hsalsa20/tweet"
|
||||
#define crypto_hashblocks_PRIMITIVE "sha512"
|
||||
#define crypto_hashblocks crypto_hashblocks_sha512
|
||||
#define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES
|
||||
#define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES
|
||||
#define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION
|
||||
#define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION
|
||||
#define crypto_hashblocks_sha512_tweet_STATEBYTES 64
|
||||
#define crypto_hashblocks_sha512_tweet_BLOCKBYTES 128
|
||||
extern int crypto_hashblocks_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
|
||||
#define crypto_hashblocks_sha512_tweet_VERSION "-"
|
||||
#define crypto_hashblocks_sha512 crypto_hashblocks_sha512_tweet
|
||||
#define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_tweet_STATEBYTES
|
||||
#define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_tweet_BLOCKBYTES
|
||||
#define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_tweet_VERSION
|
||||
#define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/tweet"
|
||||
#define crypto_hashblocks_sha256_tweet_STATEBYTES 32
|
||||
#define crypto_hashblocks_sha256_tweet_BLOCKBYTES 64
|
||||
extern int crypto_hashblocks_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
|
||||
#define crypto_hashblocks_sha256_tweet_VERSION "-"
|
||||
#define crypto_hashblocks_sha256 crypto_hashblocks_sha256_tweet
|
||||
#define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_tweet_STATEBYTES
|
||||
#define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_tweet_BLOCKBYTES
|
||||
#define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_tweet_VERSION
|
||||
#define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/tweet"
|
||||
#define crypto_hash_PRIMITIVE "sha512"
|
||||
#define crypto_hash crypto_hash_sha512
|
||||
#define crypto_hash_BYTES crypto_hash_sha512_BYTES
|
||||
#define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION
|
||||
#define crypto_hash_VERSION crypto_hash_sha512_VERSION
|
||||
#define crypto_hash_sha512_tweet_BYTES 64
|
||||
extern int crypto_hash_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
|
||||
#define crypto_hash_sha512_tweet_VERSION "-"
|
||||
#define crypto_hash_sha512 crypto_hash_sha512_tweet
|
||||
#define crypto_hash_sha512_BYTES crypto_hash_sha512_tweet_BYTES
|
||||
#define crypto_hash_sha512_VERSION crypto_hash_sha512_tweet_VERSION
|
||||
#define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/tweet"
|
||||
#define crypto_hash_sha256_tweet_BYTES 32
|
||||
extern int crypto_hash_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
|
||||
#define crypto_hash_sha256_tweet_VERSION "-"
|
||||
#define crypto_hash_sha256 crypto_hash_sha256_tweet
|
||||
#define crypto_hash_sha256_BYTES crypto_hash_sha256_tweet_BYTES
|
||||
#define crypto_hash_sha256_VERSION crypto_hash_sha256_tweet_VERSION
|
||||
#define crypto_hash_sha256_IMPLEMENTATION "crypto_hash/sha256/tweet"
|
||||
#define crypto_onetimeauth_PRIMITIVE "poly1305"
|
||||
#define crypto_onetimeauth crypto_onetimeauth_poly1305
|
||||
#define crypto_onetimeauth_verify crypto_onetimeauth_poly1305_verify
|
||||
#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES
|
||||
#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES
|
||||
#define crypto_onetimeauth_IMPLEMENTATION crypto_onetimeauth_poly1305_IMPLEMENTATION
|
||||
#define crypto_onetimeauth_VERSION crypto_onetimeauth_poly1305_VERSION
|
||||
#define crypto_onetimeauth_poly1305_tweet_BYTES 16
|
||||
#define crypto_onetimeauth_poly1305_tweet_KEYBYTES 32
|
||||
extern int crypto_onetimeauth_poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
extern int crypto_onetimeauth_poly1305_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
#define crypto_onetimeauth_poly1305_tweet_VERSION "-"
|
||||
#define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tweet
|
||||
#define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tweet_verify
|
||||
#define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tweet_BYTES
|
||||
#define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tweet_KEYBYTES
|
||||
#define crypto_onetimeauth_poly1305_VERSION crypto_onetimeauth_poly1305_tweet_VERSION
|
||||
#define crypto_onetimeauth_poly1305_IMPLEMENTATION "crypto_onetimeauth/poly1305/tweet"
|
||||
#define crypto_scalarmult_PRIMITIVE "curve25519"
|
||||
#define crypto_scalarmult crypto_scalarmult_curve25519
|
||||
#define crypto_scalarmult_base crypto_scalarmult_curve25519_base
|
||||
#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
|
||||
#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
|
||||
#define crypto_scalarmult_IMPLEMENTATION crypto_scalarmult_curve25519_IMPLEMENTATION
|
||||
#define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION
|
||||
#define crypto_scalarmult_curve25519_tweet_BYTES 32
|
||||
#define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32
|
||||
extern int crypto_scalarmult_curve25519_tweet(unsigned char *,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_scalarmult_curve25519_tweet_base(unsigned char *,const unsigned char *);
|
||||
#define crypto_scalarmult_curve25519_tweet_VERSION "-"
|
||||
#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet
|
||||
#define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tweet_base
|
||||
#define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tweet_BYTES
|
||||
#define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tweet_SCALARBYTES
|
||||
#define crypto_scalarmult_curve25519_VERSION crypto_scalarmult_curve25519_tweet_VERSION
|
||||
#define crypto_scalarmult_curve25519_IMPLEMENTATION "crypto_scalarmult/curve25519/tweet"
|
||||
#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305"
|
||||
#define crypto_secretbox crypto_secretbox_xsalsa20poly1305
|
||||
#define crypto_secretbox_open crypto_secretbox_xsalsa20poly1305_open
|
||||
#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES
|
||||
#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES
|
||||
#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES
|
||||
#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES
|
||||
#define crypto_secretbox_IMPLEMENTATION crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION
|
||||
#define crypto_secretbox_VERSION crypto_secretbox_xsalsa20poly1305_VERSION
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 32
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 24
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 32
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 16
|
||||
extern int crypto_secretbox_xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_secretbox_xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
#define crypto_secretbox_xsalsa20poly1305_tweet_VERSION "-"
|
||||
#define crypto_secretbox_xsalsa20poly1305 crypto_secretbox_xsalsa20poly1305_tweet
|
||||
#define crypto_secretbox_xsalsa20poly1305_open crypto_secretbox_xsalsa20poly1305_tweet_open
|
||||
#define crypto_secretbox_xsalsa20poly1305_KEYBYTES crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES
|
||||
#define crypto_secretbox_xsalsa20poly1305_VERSION crypto_secretbox_xsalsa20poly1305_tweet_VERSION
|
||||
#define crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION "crypto_secretbox/xsalsa20poly1305/tweet"
|
||||
#define crypto_sign_PRIMITIVE "ed25519"
|
||||
#define crypto_sign crypto_sign_ed25519
|
||||
#define crypto_sign_open crypto_sign_ed25519_open
|
||||
#define crypto_sign_keypair crypto_sign_ed25519_keypair
|
||||
#define crypto_sign_BYTES crypto_sign_ed25519_BYTES
|
||||
#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES
|
||||
#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES
|
||||
#define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION
|
||||
#define crypto_sign_VERSION crypto_sign_ed25519_VERSION
|
||||
#define crypto_sign_ed25519_tweet_BYTES 64
|
||||
#define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32
|
||||
#define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64
|
||||
extern int crypto_sign_ed25519_tweet(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
extern int crypto_sign_ed25519_tweet_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
|
||||
extern int crypto_sign_ed25519_tweet_keypair(unsigned char *,unsigned char *);
|
||||
#define crypto_sign_ed25519_tweet_VERSION "-"
|
||||
#define crypto_sign_ed25519 crypto_sign_ed25519_tweet
|
||||
#define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open
|
||||
#define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair
|
||||
#define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES
|
||||
#define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tweet_PUBLICKEYBYTES
|
||||
#define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tweet_SECRETKEYBYTES
|
||||
#define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION
|
||||
#define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet"
|
||||
#define crypto_stream_PRIMITIVE "xsalsa20"
|
||||
#define crypto_stream crypto_stream_xsalsa20
|
||||
#define crypto_stream_xor crypto_stream_xsalsa20_xor
|
||||
#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES
|
||||
#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES
|
||||
#define crypto_stream_IMPLEMENTATION crypto_stream_xsalsa20_IMPLEMENTATION
|
||||
#define crypto_stream_VERSION crypto_stream_xsalsa20_VERSION
|
||||
#define crypto_stream_xsalsa20_tweet_KEYBYTES 32
|
||||
#define crypto_stream_xsalsa20_tweet_NONCEBYTES 24
|
||||
extern int crypto_stream_xsalsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_stream_xsalsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
#define crypto_stream_xsalsa20_tweet_VERSION "-"
|
||||
#define crypto_stream_xsalsa20 crypto_stream_xsalsa20_tweet
|
||||
#define crypto_stream_xsalsa20_xor crypto_stream_xsalsa20_tweet_xor
|
||||
#define crypto_stream_xsalsa20_KEYBYTES crypto_stream_xsalsa20_tweet_KEYBYTES
|
||||
#define crypto_stream_xsalsa20_NONCEBYTES crypto_stream_xsalsa20_tweet_NONCEBYTES
|
||||
#define crypto_stream_xsalsa20_VERSION crypto_stream_xsalsa20_tweet_VERSION
|
||||
#define crypto_stream_xsalsa20_IMPLEMENTATION "crypto_stream/xsalsa20/tweet"
|
||||
#define crypto_stream_salsa20_tweet_KEYBYTES 32
|
||||
#define crypto_stream_salsa20_tweet_NONCEBYTES 8
|
||||
extern int crypto_stream_salsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
extern int crypto_stream_salsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
|
||||
#define crypto_stream_salsa20_tweet_VERSION "-"
|
||||
#define crypto_stream_salsa20 crypto_stream_salsa20_tweet
|
||||
#define crypto_stream_salsa20_xor crypto_stream_salsa20_tweet_xor
|
||||
#define crypto_stream_salsa20_KEYBYTES crypto_stream_salsa20_tweet_KEYBYTES
|
||||
#define crypto_stream_salsa20_NONCEBYTES crypto_stream_salsa20_tweet_NONCEBYTES
|
||||
#define crypto_stream_salsa20_VERSION crypto_stream_salsa20_tweet_VERSION
|
||||
#define crypto_stream_salsa20_IMPLEMENTATION "crypto_stream/salsa20/tweet"
|
||||
#define crypto_verify_PRIMITIVE "16"
|
||||
#define crypto_verify crypto_verify_16
|
||||
#define crypto_verify_BYTES crypto_verify_16_BYTES
|
||||
#define crypto_verify_IMPLEMENTATION crypto_verify_16_IMPLEMENTATION
|
||||
#define crypto_verify_VERSION crypto_verify_16_VERSION
|
||||
#define crypto_verify_16_tweet_BYTES 16
|
||||
extern int crypto_verify_16_tweet(const unsigned char *,const unsigned char *);
|
||||
#define crypto_verify_16_tweet_VERSION "-"
|
||||
#define crypto_verify_16 crypto_verify_16_tweet
|
||||
#define crypto_verify_16_BYTES crypto_verify_16_tweet_BYTES
|
||||
#define crypto_verify_16_VERSION crypto_verify_16_tweet_VERSION
|
||||
#define crypto_verify_16_IMPLEMENTATION "crypto_verify/16/tweet"
|
||||
#define crypto_verify_32_tweet_BYTES 32
|
||||
extern int crypto_verify_32_tweet(const unsigned char *,const unsigned char *);
|
||||
#define crypto_verify_32_tweet_VERSION "-"
|
||||
#define crypto_verify_32 crypto_verify_32_tweet
|
||||
#define crypto_verify_32_BYTES crypto_verify_32_tweet_BYTES
|
||||
#define crypto_verify_32_VERSION crypto_verify_32_tweet_VERSION
|
||||
#define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/tweet"
|
||||
#endif
|
||||
18
src/tools/web_api/registration.mail.dist
Normal file
18
src/tools/web_api/registration.mail.dist
Normal file
@@ -0,0 +1,18 @@
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd
|
||||
Content-Type: text/plain
|
||||
|
||||
Please open the following link in your webbrowser to confirm your new WoW account:
|
||||
<insert-url>
|
||||
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd
|
||||
Content-Type: text/html
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>WoW Registration Confirmation</title>
|
||||
</head>
|
||||
<body>Please click the following link to confirm your new WoW account:<br>
|
||||
<a href="<insert-url>"><insert-url></a>
|
||||
</body></html>
|
||||
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd--
|
||||
18
src/tools/web_api/reset.mail.dist
Normal file
18
src/tools/web_api/reset.mail.dist
Normal file
@@ -0,0 +1,18 @@
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd
|
||||
Content-Type: text/plain
|
||||
|
||||
Please open the following link in your webbrowser to confirm the new password for your WoW account:
|
||||
<insert-url>
|
||||
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd
|
||||
Content-Type: text/html
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>WoW Password Reset Confirmation</title>
|
||||
</head>
|
||||
<body>Please click the following link to confirm the new password for your WoW account:<br>
|
||||
<a href="<insert-url>"><insert-url></a>
|
||||
</body></html>
|
||||
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd--
|
||||
2086
src/tools/web_api/src/main.cpp
Normal file
2086
src/tools/web_api/src/main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
18
src/tools/web_api/validation.mail.dist
Normal file
18
src/tools/web_api/validation.mail.dist
Normal file
@@ -0,0 +1,18 @@
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd
|
||||
Content-Type: text/plain
|
||||
|
||||
Please open the following link in your webbrowser to continue upgrading your WoW account:
|
||||
<insert-url>
|
||||
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd
|
||||
Content-Type: text/html
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>WoW Account Upgrade Email Validation</title>
|
||||
</head>
|
||||
<body>Please click the following link to continue upgrading your WoW account:<br>
|
||||
<a href="<insert-url>"><insert-url></a>
|
||||
</body></html>
|
||||
|
||||
--dakjqwmnejadhasdkljkaeiasndansdahjdhjasd--
|
||||
171
src/tools/web_api/webapi.conf.dist
Normal file
171
src/tools/web_api/webapi.conf.dist
Normal file
@@ -0,0 +1,171 @@
|
||||
###############################################
|
||||
# Trinity Core Auth Server configuration file #
|
||||
###############################################
|
||||
[webapi]
|
||||
|
||||
###################################################################################################
|
||||
# SECTION INDEX
|
||||
#
|
||||
# EXAMPLE CONFIG
|
||||
# AUTH SERVER SETTINGS
|
||||
# MYSQL SETTINGS
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# EXAMPLE CONFIG
|
||||
#
|
||||
# Variable
|
||||
# Description: Brief description what the variable is doing.
|
||||
# Important: Annotation for important things about this variable.
|
||||
# Example: "Example, i.e. if the value is a string"
|
||||
# Default: 10 - (Enabled|Comment|Variable name in case of grouped config options)
|
||||
# 0 - (Disabled|Comment|Variable name in case of grouped config options)
|
||||
#
|
||||
# Note to developers:
|
||||
# - Copy this example to keep the formatting.
|
||||
# - Line breaks should be at column 100.
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# AUTH SERVER SETTINGS
|
||||
#
|
||||
# Port
|
||||
# Description: TCP port to reach the webapi server.
|
||||
# Default: 8090
|
||||
|
||||
Port = 8090
|
||||
|
||||
#
|
||||
#
|
||||
# BindIP
|
||||
# Description: Bind webapi server to IP/hostname
|
||||
# Default: "127.0.0.1" - (Bind to localhost)
|
||||
|
||||
BindIP = "127.0.0.1"
|
||||
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# MYSQL SETTINGS
|
||||
#
|
||||
# LoginDatabaseInfo
|
||||
# Description: Database connection settings for the realm server.
|
||||
# Example: "hostname;port;username;password;database"
|
||||
# ".;somenumber;username;password;database" - (Use named pipes on Windows
|
||||
# "enable-named-pipe" to [mysqld]
|
||||
# section my.ini)
|
||||
# ".;/path/to/unix_socket;username;password;database" - (use Unix sockets on
|
||||
# Unix/Linux)
|
||||
# Default: "127.0.0.1;3306;trinity;trinity;auth"
|
||||
|
||||
LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth"
|
||||
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# SMTP SERVER SETTINGS
|
||||
#
|
||||
# Port
|
||||
# Description: TCP port to reach the webapi server.
|
||||
# Default: 25
|
||||
|
||||
SMTPPort = 25
|
||||
|
||||
#
|
||||
#
|
||||
# BindIP
|
||||
# Description: Bind webapi server to IP/hostname
|
||||
# Default: "127.0.0.1" - (Bind to localhost)
|
||||
|
||||
SMTPIP = "127.0.0.1"
|
||||
|
||||
SMTPUser = "user"
|
||||
SMTPPassword = "password"
|
||||
|
||||
SMTPFromAddress = "no-reply@wow.com"
|
||||
SMTPFromName = "WoW"
|
||||
|
||||
SMTPMailRegistrationSubject = "WoW - Registration Confirmation"
|
||||
SMTPMailResetSubject = "WoW - Password Reset Confirmation"
|
||||
SMTPMailValidationSubject = "WoW - Account Upgrade Email Validation"
|
||||
SMTPMailConfirmationSubject = "WoW - Account Upgrade Confirmation"
|
||||
|
||||
SMTPReturnDomain = "https://wow.com"
|
||||
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# NEWSLETTER SETTINGS
|
||||
|
||||
NewsLetterUnsubDomain = "https://unsubscribe.wow.com/unsubscribe/"
|
||||
NewsLetterSubject = "WoW Subject"
|
||||
NewsLetterMailForUnsubscribe = "unsubscribe@wow.com"
|
||||
NewsLetterSecondsBetweenMails = 5
|
||||
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# IFRAME SETTINGS
|
||||
|
||||
RefUrlHeader = <html><head></head><body><div>
|
||||
RefUrlFooter = </div></body></html>
|
||||
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# REAL IP SETTINGS
|
||||
|
||||
# IpFromHeader = X-Real-IP
|
||||
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
###################################################################################################
|
||||
# VOTE SETTINGS
|
||||
|
||||
WebsiteName1 = TopG
|
||||
CallbackKeyName1 = p_resp
|
||||
CallbackHostname1 = monitor.topg.org
|
||||
CallbackUrl1 = /callback/topg-vote/api
|
||||
VoteUrl1 = https://topg.org/CATEGORY/in-SITEID-
|
||||
VoteToken1 = 1
|
||||
VoteTokensGiven1 = 2
|
||||
|
||||
WebsiteName2 = XtremeTop100
|
||||
CallbackKeyName2 = custom
|
||||
CallbackHostname2 = xtremetop100.com
|
||||
CallbackUrl2 = /callback/xtremetop100-vote/api
|
||||
VoteUrl2 = https://www.xtremetop100.com/in.php?site=SITEID&postback=
|
||||
VoteToken2 = 1
|
||||
VoteTokensGiven2 = 0
|
||||
|
||||
WebisteName3 = ArenaTop100
|
||||
CallbackKeyName3 = userid
|
||||
CallbackIps3 = 0.0.0.0
|
||||
CallbackUrl3 = /callback/arenatop100-vote/api
|
||||
VoteUrl3 = https://www.arena-top100.com/index.php?a=in&u=ARENA-TOP100-USERNAME&id=
|
||||
CheckKeyName3 = voted
|
||||
CheckKeyValue3 = 1
|
||||
VoteToken3 = 1
|
||||
VoteTokensGiven3 = 1
|
||||
|
||||
WebisteName4 = GamingTop100
|
||||
CallbackKeyName4 = userid
|
||||
CallbackHostname4 = gamingtop100.net
|
||||
CallbackUrl4 = /callback/gamingtop100-vote/api
|
||||
CallbackIdOnlyDigits4 = 1
|
||||
VoteUrl4 = http://gamingtop100.net/in-SITEID-
|
||||
VoteToken4 = 1
|
||||
VoteTokensGiven4 = 1
|
||||
Reference in New Issue
Block a user