This commit is contained in:
Soggy_Pancake 2026-04-13 07:44:23 +02:00 committed by GitHub
commit 55ea06ba21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
121 changed files with 6833 additions and 805 deletions

View file

@ -1,10 +1,239 @@
#include "stdafx.h"
#include "Textures.h"
#include "StitchedTexture.h"
#include "AbstractTexturePack.h"
#include "TexturePackRepository.h"
#include "..\Minecraft.World\InputOutputStream.h"
#include "..\Minecraft.World\FileInputStream.h"
#include "..\Minecraft.World\StringHelpers.h"
#include "Common/UI/UI.h"
const unordered_map<std::wstring, std::wstring> AbstractTexturePack::INDEXED_TO_JAVA_MAP = {
{L"res/misc/pumpkinblur.png", L"misc/pumpkinblur.png"},
// L"%blur%/misc/vignette", // Not currently used
{L"res/misc/shadow", L""},
// L"/achievement/bg", // Not currently used
{L"art/kz", L""},
{L"res/environment/clouds.png", L"environment/clouds.png"},
{L"res/environment/rain.png", L"environment/rain.png"},
{L"res/environment/snow.png", L"environment/snow.png"},
{L"gui/gui", L""},
{L"gui/icons", L""},
//{L"item/arrows", L""},
//{L"item/boat", L""},
//{L"item/cart", L""},
//{L"item/sign", L""},
{L"res/misc/mapbg", L""},
{L"res/misc/mapicons", L""},
{L"res/misc/water", L""},
{L"res/misc/footprint", L""},
//{L"mob/saddle", L""},
{L"res/res/mob/sheep_fur.png", L"entity/sheep/sheep_fur.png"},
{L"res/mob/spider_eyes.png", L""},
{L"res/particles", L""},
{L"res/mob/chicken.png", L"entity/chicken.png"},
{L"res/mob/cow.png", L"entity/cow/cow.png"},
{L"res/mob/pig.png", L"entity/pig/pig.png"},
{L"res/mob/sheep.png", L"entity/sheep/sheep.png"},
{L"res/mob/squid.png", L"entity/squid/squid.png"},
{L"res/mob/wolf.png", L"entity/wolf/wolf.png"},
{L"res/mob/wolf_tame.png", L"entity/wolf/wolf_tame.png"},
{L"res/mob/wolf_angry.png", L"entity/wolf/wolf_angry.png"},
{L"res/mob/creeper.png", L"entity/creeper/creeper.png"},
{L"res/mob/ghast.png", L"entity/ghast/ghast.png"},
{L"res/mob/ghast_fire.png", L"entity/ghast/ghast_shooting.png"},
//{L"res/mob/zombie", L""}, // zombie uses 64x texture
//{L"res/mob/pigzombie", L""}, // rip
{L"res/mob/skeleton.png", L"entity/skeleton/skeleton.png"},
{L"res/mob/slime.png", L"entity/slime/slime.png"},
{L"res/mob/spider.png", L"entity/spider/spider.png"},
//{L"mob/char", L""},
//{L"mob/char1", L""},
//{L"mob/char2", L""},
//{L"mob/char3", L""},
//{L"mob/char4", L""},
//{L"mob/char5", L""},
//{L"mob/char6", L""},
//{L"mob/char7", L""},
{L"terrain/moon", L""},
{L"terrain/sun", L""},
{L"armor/power", L""},
// 1.8.2
{L"res/mob/cavespider.png", L"entity/spider/cave_spider.png"},
{L"res/mob/enderman.png", L"entity/enderman/enderman.png"},
{L"res/mob/silverfish.png", L"entity/silverfish.png"},
{L"res/mob/enderman_eyes.png", L"entity/enderman/enderman_eyes.png"},
//{L"res/misc/explosion", L""}, // not bothering to reatlas them rn
{L"res/item/xporb.png", L"entity/experience_orb.png"},
{L"res/item/chest.png", L"entity/chest/normal.png"},
//{L"item/largechest", L"entity/chest/normal"}, // was split in half
// 1.3.2
{L"res/item/enderchest.png", L"entity/chest/ender.png"},
// 1.0.1
{L"res/mob/redcow.png", L"entity/cow/mooshroom.png"},
//{L"mob/snowman", L""},
//{L"mob/enderdragon/ender", L""},
{L"res/mob/fire.png", L"entity/blaze.png"},
{L"res/mob/lava.png", L"entity/slime/magmacube.png"},
//{L"mob/villager/villager", L""},
//{L"mob/villager/farmer", L""},
//{L"mob/villager/librarian", L""},
//{L"mob/villager/priest", L""},
//{L"mob/villager/smith", L""},
//{L"mob/villager/butcher", L""},
{L"res/mob/enderdragon/crystal.png", L"entity/end_crystal/end_crystal.png"},
//{L"mob/enderdragon/shuffle", L""},
{L"res/mob/enderdragon/beam.png", L"entity/end_crystal/end_crystal_beam.png"},
//{L"mob/enderdragon/ender_eyes", L""},
{L"res/misc/glint.png", L"misc/enchanted_item_glint.png"},
//{L"item/book", L""},
{L"res/misc/tunnel.png", L"environment/end_sky.png"},
{L"res/misc/particlefield.png", L"entity/end_portal.png"},
{L"res/terrain/moon_phases.png", L"environment/moon_phases.png"},
// 1.2.3
{L"res/mob/ozelot.png", L"entity/cat/ocelot.png"},
{L"res/mob/cat_black.png", L"entity/cat/black.png"},
{L"res/mob/cat_red.png", L"entity/cat/red.png"},
{L"res/mob/cat_siamese.png", L"entity/cat/siamese.png"},
{L"res/mob/villager_golem.png", L"entity/iron_golem.png"},
{L"res/mob/skeleton_wither.png", L"entity/wither_skeleton.png"},
// TU 14
{L"res/mob/wolf_collar.png", L"entity/wolf/wolf_collar.png"},
//{L"mob/zombie_villager", L""},
// 1.6.4
{L"res/item/lead_knot.png", L"entity/lead_knot.png"},
{L"res/misc/beacon_beam.png", L"entity/beacon_beam.png"},
//{L"res/mob/bat.png", L"entity/bat.png"}, // new uvs is broken
// incompatible horse armor
//{L"mob/horse/donkey", L""},
//{L"mob/horse/horse_black", L""},
//{L"mob/horse/horse_brown", L""},
//{L"mob/horse/horse_chestnut", L""},
//{L"mob/horse/horse_creamy", L""},
//{L"mob/horse/horse_darkbrown", L""},
//{L"mob/horse/horse_gray", L""},
//{L"mob/horse/horse_markings_blackdots", L""},
//{L"mob/horse/horse_markings_white", L""},
//{L"mob/horse/horse_markings_whitedots", L""},
//{L"mob/horse/horse_markings_whitefield", L""},
//{L"mob/horse/horse_skeleton", L""},
//{L"mob/horse/horse_white", L""},
//{L"mob/horse/horse_zombie", L""},
//{L"mob/horse/mule", L""},
//{L"mob/horse/armor/horse_armor_diamond", L""},
//{L"mob/horse/armor/horse_armor_gold", L""},
//{L"mob/horse/armor/horse_armor_iron", L""},
{ L"res/mob/witch", L"entity/witch.png" },
{ L"res/mob/wither/wither.png", L"entity/wither/wither.png" },
{ L"res/mob/wither/wither_armor.png", L"entity/wither/wither_armor.png" },
{ L"res/mob/wither/wither_invulnerable.png", L"entity/wither/wither_invulnerable.png" },
{ L"res/item/trapped.png", L"entity/chest/trapped.png" },
//{ L"item/trapped_double", L"" },
//L"item/christmas",
//L"item/christmas_double",
#ifdef _LARGE_WORLDS
//{L"misc/additionalmapicons", L""},
#endif
//{L"font/Default", L""},
//{L"font/alternate", L""},
// skin packs
/* {L"/SP1", L""},
{L"/SP2", L""},
{L"/SP3", L""},
{L"/SPF", L""},
{ L""},
{// themes L""},
{L"/ThSt", L""},
{L"/ThIr", L""},
{L"/ThGo", L""},
{L"/ThDi", L""},
{ L""},
{// gamerpics L""},
{L"/GPAn", L""},
{L"/GPCo", L""},
{L"/GPEn", L""},
{L"/GPFo", L""},
{L"/GPTo", L""},
{L"/GPBA", L""},
{L"/GPFa", L""},
{L"/GPME", L""},
{L"/GPMF", L""},
{L"/GPMM", L""},
{L"/GPSE", L""},
{ L""},
{// avatar items L""},
{ L""},
{L"/AH_0006", L""},
{L"/AH_0003", L""},
{L"/AH_0007", L""},
{L"/AH_0005", L""},
{L"/AH_0004", L""},
{L"/AH_0001", L""},
{L"/AH_0002", L""},
{L"/AT_0001", L""},
{L"/AT_0002", L""},
{L"/AT_0003", L""},
{L"/AT_0004", L""},
{L"/AT_0005", L""},
{L"/AT_0006", L""},
{L"/AT_0007", L""},
{L"/AT_0008", L""},
{L"/AT_0009", L""},
{L"/AT_0010", L""},
{L"/AT_0011", L""},
{L"/AT_0012", L""},
{L"/AP_0001", L""},
{L"/AP_0002", L""},
{L"/AP_0003", L""},
{L"/AP_0004", L""},
{L"/AP_0005", L""},
{L"/AP_0006", L""},
{L"/AP_0007", L""},
{L"/AP_0009", L""},
{L"/AP_0010", L""},
{L"/AP_0011", L""},
{L"/AP_0012", L""},
{L"/AP_0013", L""},
{L"/AP_0014", L""},
{L"/AP_0015", L""},
{L"/AP_0016", L""},
{L"/AP_0017", L""},
{L"/AP_0018", L""},
{L"/AA_0001", L""},
{L"/AT_0013", L""},
{L"/AT_0014", L""},
{L"/AT_0015", L""},
{L"/AT_0016", L""},
{L"/AT_0017", L""},
{L"/AT_0018", L""},
{L"/AP_0019", L""},
{L"/AP_0020", L""},
{L"/AP_0021", L""},
{L"/AP_0022", L""},
{L"/AP_0023", L""},
{L"/AH_0008", L""},
{L"/AH_0009", L""},*/
//{L"gui/items", L""},
//{L"terrain", L""}
};
AbstractTexturePack::AbstractTexturePack(DWORD id, File *file, const wstring &name, TexturePack *fallback) : id(id), name(name)
{
// 4J init
@ -102,6 +331,22 @@ void AbstractTexturePack::loadName()
{
}
void AbstractTexturePack::checkTexSize() {
BufferedImage* img = getImageResource(L"dirt.png", true);
texSize = 16;
if (img != nullptr) {
int width = img->getWidth();
int height = img->getHeight();
if (width != height || width <= 0 || height <= 0) {
app.DebugPrintf("Warning: Texture pack contains texture with bad size: %d x %d\n", width, height);
__debugbreak();
}
else
texSize = width;
delete img;
}
}
InputStream *AbstractTexturePack::getResource(const wstring &name, bool allowFallback) //throws IOException
{
app.DebugPrintf("texture - %ls\n",name.c_str());
@ -148,8 +393,19 @@ void AbstractTexturePack::load(Textures *textures)
bool AbstractTexturePack::hasFile(const wstring &name, bool allowFallback)
{
if (name == L"res/terrain.png" && terrainAtlas != nullptr)
return true;
if (name == L"res/items.png" && itemAtlas != nullptr)
return true;
bool hasFile = this->hasFile(name);
auto it = INDEXED_TO_JAVA_MAP.find(name);
if (it != INDEXED_TO_JAVA_MAP.end()) {
hasFile = this->hasFile(L"assets/minecraft/textures/" + it->second);
}
return !hasFile && (allowFallback && fallback != nullptr) ? fallback->hasFile(name, allowFallback) : hasFile;
}
@ -188,7 +444,7 @@ wstring AbstractTexturePack::getAnimationString(const wstring &textureName, cons
wstring animationDefinitionFile = textureName + L".txt";
bool requiresFallback = !hasFile(L"\\" + textureName + L".png", false);
wstring result = L"";
InputStream *fileStream = getResource(L"\\" + path + animationDefinitionFile, requiresFallback);
@ -220,10 +476,491 @@ wstring AbstractTexturePack::getAnimationString(const wstring &textureName, cons
return result;
}
struct UV {
float x0, y0, x1, y1;
float width(float imgSize) {
return (x1 - x0) * imgSize - 1;
}
float height(float imgSize) {
return (y1 - y0) * imgSize - 1;
}
UV operator /=(const float other) {
x0 /= other;
y0 /= other;
x1 /= other;
y1 /= other;
return *this;
}
};
BufferedImage* AbstractTexturePack::getBedTex(std::wstring name) {
if (bedTexCache.get() == nullptr) {
BufferedImage* bedtex = getImageResource(L"assets/minecraft/textures/entity/bed/red.png", true);
if (bedtex != nullptr) {
if (bedtex->getWidth() < 0 || bedtex->getHeight() < 0)
return nullptr;
int len = bedtex->getWidth() * bedtex->getHeight();
bedTexCache = std::make_unique<BufferedImage>(bedtex->getWidth(), bedtex->getHeight(), 0);
memcpy(bedTexCache->getData(), bedtex->getData(), len * sizeof(int));
delete bedtex;
}
}
if (bedTexCache.get() == nullptr) { // todo: rip from og atlas
app.DebugPrintf("Failed to load bed texture, returning null\n");
return nullptr;
}
// hardcoded in java and no way to load it here, I hate hardcoding this but its what I got
UV feetEnd, feetEndStubL, feetEndStubR,
feetSide, feetSideStub,
headSide, headSideStub,
headEnd, headEndStubL, headEndStubR,
feetFace, headFace;
// This code is extremely dumb, x0 and y0 must always be less than x1 and y1
// These are the top left of the pixel, so add 1 extra for x1 and y1
const float baseBedTexSize = 64; // original bed tex size, dont change unless new base game res changes
headFace = { 6, 6, 22, 22 };
feetFace = { 6, 28, 22, 44 };
feetFace /= baseBedTexSize; headFace /= baseBedTexSize;
feetEnd = { 22, 22, 38, 28 };
headEnd = { 6, 0, 22, 6 };
feetEnd /= baseBedTexSize; headEnd /= baseBedTexSize;
feetEndStubL = { 53, 3, 56, 6 };
feetEndStubR = { 50, 15, 53, 18 };
feetEndStubL /= baseBedTexSize; feetEndStubR /= baseBedTexSize;
headEndStubL = { 53, 21, 56, 24 };
headEndStubR = { 50, 9, 53, 12 };
headEndStubL /= baseBedTexSize; headEndStubR /= baseBedTexSize;
headSide = { 22, 6, 28, 22 };
headSideStub = { 50, 21, 53, 24 };
headSide /= baseBedTexSize; headSideStub /= baseBedTexSize;
feetSide = { 22, 28, 28, 44 };
feetSideStub = { 53, 15, 56, 18 };
feetSide /= baseBedTexSize; feetSideStub /= baseBedTexSize;
// Output uvs
UV outBedBody, outStubL, outStubR, outBedFace;
outBedBody = { 0, 7, 16, 13 };
outStubL = { 0, 13, 3, 16 };
outStubR = { 13, 13, 16, 16 };
outBedFace = { 0, 0, 16, 16 };
outBedBody /= 16; outStubL /= 16; outStubR /= 16; outBedFace /= 16;
const int bedTexSize = bedTexCache->getWidth();
auto workTex = new BufferedImage(texSize, texSize, GL_RGBA);
auto workPix = reinterpret_cast<Pixel*>(workTex->getData());
auto bedPix = reinterpret_cast<Pixel*>(bedTexCache->getData());
memset(workPix, 0, texSize * texSize * sizeof(Pixel));
if (name == L"bed_feet_end") {
// side body minus legs
for (int y = 0; y <= outBedBody.height(texSize); y++)
for (int x = 0; x <= outBedBody.width(texSize); x++) {
// first get raw src.x0 of tex to sample from current uv pixel, then current uv value * targetUV dimension
// hopefully this can sample any size as long as dst is always equal or larger res
int srcx = roundf((feetEnd.x0 * bedTexSize) + (x / outBedBody.width(texSize)) * feetEnd.width(bedTexSize));
int srcy = roundf((feetEnd.y0 * bedTexSize) + (1 - (y / outBedBody.height(texSize))) * feetEnd.height(bedTexSize));
int dstx = roundf((outBedBody.x0 * texSize) + (x / outBedBody.width(texSize)) * outBedBody.width(texSize));
int dsty = roundf((outBedBody.y0 * texSize) + (y / outBedBody.height(texSize)) * outBedBody.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
// left leg
for (int y = 0; y <= outStubL.height(texSize); y++)
for (int x = 0; x <= outStubL.width(texSize); x++) {
int srcx = roundf((feetEndStubL.x0 * bedTexSize) + (x / outStubL.height(texSize)) * feetEndStubL.width(bedTexSize));
int srcy = roundf((feetEndStubL.y0 * bedTexSize) + (y / outStubL.width(texSize)) * feetEndStubL.height(bedTexSize));
int dstx = roundf((outStubL.x0 * texSize) + (x / outStubL.width(texSize)) * outStubL.width(texSize));
int dsty = roundf((outStubL.y0 * texSize) + (y / outStubL.height(texSize)) * outStubL.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
// right leg
for (int y = 0; y <= outStubR.height(texSize); y++)
for (int x = 0; x <= outStubR.width(texSize); x++) {
int srcx = roundf((feetEndStubR.x0 * bedTexSize) + (x / outStubR.height(texSize)) * feetEndStubR.width(bedTexSize));
int srcy = roundf((feetEndStubR.y0 * bedTexSize) + (y / outStubR.width(texSize)) * feetEndStubR.height(bedTexSize));
int dstx = roundf((outStubR.x0 * texSize) + (x / outStubR.width(texSize)) * outStubR.width(texSize));
int dsty = roundf((outStubR.y0 * texSize) + (y / outStubR.height(texSize)) * outStubR.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
return workTex;
} else if (name == L"bed_feet_side") {
// side body minus leg
for (int y = 0; y <= outBedBody.height(texSize); y++)
for (int x = 0; x <= outBedBody.width(texSize); x++) {
// first get raw src.x0 of tex to sample from current uv pixel, then current uv value * targetUV dimension
// hopefully this can sample any size as long as dst is always equal or larger res
int srcx = roundf((feetSide.x0 * bedTexSize) + (y / outBedBody.height(texSize)) * feetSide.width(bedTexSize));
int srcy = roundf((feetSide.y0 * bedTexSize) + (1 - (x / outBedBody.width(texSize))) * feetSide.height(bedTexSize));
int dstx = roundf((outBedBody.x0 * texSize) + (x / outBedBody.width(texSize)) * outBedBody.width(texSize));
int dsty = roundf((outBedBody.y0 * texSize) + (y / outBedBody.height(texSize)) * outBedBody.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
// side leg
for (int y = 0; y <= outStubL.height(texSize); y++)
for (int x = 0; x <= outStubL.width(texSize); x++) {
int srcx = roundf((feetSideStub.x0 * bedTexSize) + (x / outStubL.height(texSize)) * feetSideStub.width(bedTexSize));
int srcy = roundf((feetSideStub.y0 * bedTexSize) + (y / outStubL.width(texSize)) * feetSideStub.height(bedTexSize));
int dstx = roundf((outStubL.x0 * texSize) + (x / outStubL.width(texSize)) * outStubL.width(texSize));
int dsty = roundf((outStubL.y0 * texSize) + (y / outStubL.height(texSize)) * outStubL.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
return workTex;
} else if (name == L"bed_head_side") {
// side body minus leg
for (int y = 0; y <= outBedBody.height(texSize); y++)
for (int x = 0; x <= outBedBody.width(texSize); x++) {
// first get raw src.x0 of tex to sample from current uv pixel, then current uv value * targetUV dimension
// hopefully this can sample any size as long as dst is always equal or larger res
int srcx = roundf((headSide.x0 * bedTexSize) + (y / outBedBody.height(texSize)) * headSide.width(bedTexSize));
int srcy = roundf((headSide.y0 * bedTexSize) + (1 - (x / outBedBody.width(texSize))) * headSide.height(bedTexSize));
int dstx = roundf((outBedBody.x0 * texSize) + (x / outBedBody.width(texSize)) * outBedBody.width(texSize));
int dsty = roundf((outBedBody.y0 * texSize) + (y / outBedBody.height(texSize)) * outBedBody.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
// side leg
for (int y = 0; y <= outStubR.height(texSize); y++)
for (int x = 0; x <= outStubR.width(texSize); x++) {
int srcx = roundf((headSideStub.x0 * bedTexSize) + (x / outStubR.height(texSize)) * headSideStub.width(bedTexSize));
int srcy = roundf((headSideStub.y0 * bedTexSize) + (y / outStubR.width(texSize)) * headSideStub.height(bedTexSize));
int dstx = roundf((outStubR.x0 * texSize) + (x / outStubR.width(texSize)) * outStubR.width(texSize));
int dsty = roundf((outStubR.y0 * texSize) + (y / outStubR.height(texSize)) * outStubR.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
return workTex;
} else if (name == L"bed_head_end") {
// side body minus legs
for (int y = 0; y <= outBedBody.height(texSize); y++)
for (int x = 0; x <= outBedBody.width(texSize); x++) {
// first get raw src.x0 of tex to sample from current uv pixel, then current uv value * targetUV dimension
// hopefully this can sample any size as long as dst is always equal or larger res
int srcx = roundf((headEnd.x0 * bedTexSize) + (x / outBedBody.width(texSize)) * headEnd.width(bedTexSize));
int srcy = roundf((headEnd.y0 * bedTexSize) + (1 - (y / outBedBody.height(texSize))) * headEnd.height(bedTexSize));
int dstx = roundf((outBedBody.x0 * texSize) + (x / outBedBody.width(texSize)) * outBedBody.width(texSize));
int dsty = roundf((outBedBody.y0 * texSize) + (y / outBedBody.height(texSize)) * outBedBody.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
// left leg
for (int y = 0; y <= outStubL.height(texSize); y++)
for (int x = 0; x <= outStubL.width(texSize); x++) {
int srcx = roundf((headEndStubL.x0 * bedTexSize) + (x / outStubL.height(texSize)) * headEndStubL.width(bedTexSize));
int srcy = roundf((headEndStubL.y0 * bedTexSize) + (y / outStubL.width(texSize)) * headEndStubL.height(bedTexSize));
int dstx = roundf((outStubL.x0 * texSize) + (x / outStubL.width(texSize)) * outStubL.width(texSize));
int dsty = roundf((outStubL.y0 * texSize) + (y / outStubL.height(texSize)) * outStubL.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
// right leg
for (int y = 0; y <= outStubR.height(texSize); y++)
for (int x = 0; x <= outStubR.width(texSize); x++) {
int srcx = roundf((headEndStubR.x0 * bedTexSize) + (x / outStubR.height(texSize)) * headEndStubR.width(bedTexSize));
int srcy = roundf((headEndStubR.y0 * bedTexSize) + (y / outStubR.width(texSize)) * headEndStubR.height(bedTexSize));
int dstx = roundf((outStubR.x0 * texSize) + (x / outStubR.width(texSize)) * outStubR.width(texSize));
int dsty = roundf((outStubR.y0 * texSize) + (y / outStubR.height(texSize)) * outStubR.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
return workTex;
} else if (name == L"bed_head_top") {
for (int y = 0; y <= outBedFace.height(texSize); y++)
for (int x = 0; x <= outBedFace.width(texSize); x++) {
int srcx = roundf((headFace.x0 * bedTexSize) + (x / outBedFace.width(texSize)) * headFace.width(bedTexSize));
int srcy = roundf((headFace.y0 * bedTexSize) + (1 - (y / outBedFace.height(texSize))) * headFace.height(bedTexSize));
int dstx = roundf((outBedFace.x0 * texSize) + (y / outBedFace.width(texSize)) * outBedFace.width(texSize));
int dsty = roundf((outBedFace.y0 * texSize) + (x / outBedFace.height(texSize)) * outBedFace.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
return workTex;
} else if (name == L"bed_feet_top") {
for (int y = 0; y <= outBedFace.height(texSize); y++)
for (int x = 0; x <= outBedFace.width(texSize); x++) {
int srcx = roundf((feetFace.x0 * bedTexSize) + (x / outBedFace.width(texSize)) * feetFace.width(bedTexSize));
int srcy = roundf((feetFace.y0 * bedTexSize) + (1 - (y / outBedFace.height(texSize))) * feetFace.height(bedTexSize));
int dstx = roundf((outBedFace.x0 * texSize) + (y / outBedFace.width(texSize)) * outBedFace.width(texSize));
int dsty = roundf((outBedFace.y0 * texSize) + (x / outBedFace.height(texSize)) * outBedFace.height(texSize));
int srcIdx = srcy * bedTexCache->getWidth() + srcx;
int dstIdx = dsty * texSize + dstx;
(&workPix[dstIdx])->raw = (&bedPix[srcIdx])->raw;
}
return workTex;
}
return workTex;
}
BufferedImage* AbstractTexturePack::grabFromDefault(pair<wstring, Icon*> item, Pixel* ogAtlas, pair<int, int> ogDimensions) {
auto preStitched = static_cast<StitchedTexture*>(item.second);
auto imag = new BufferedImage(texSize, texSize, GL_RGBA);
auto pixels = reinterpret_cast<Pixel*>(imag->getData());
int x = preStitched->getU0() * ogDimensions.first;
int y = preStitched->getV0() * ogDimensions.second;
for (int j = 0; j < texSize * texSize; j++) {
int srcx = x + ((j % texSize) / (float)texSize) * 16;
int srcy = y + ((j / texSize) / (float)texSize) * 16;
(&pixels[j])->raw = ogAtlas[srcx + (srcy * 256)].raw;
}
return imag;
}
BufferedImage* getDefaultAtlas(std::wstring atlasFile) {
auto defaultPack = Minecraft::GetInstance()->skins->getDefault();
auto defaultPath = defaultPack->getPath(true);
auto terrainFile = File(defaultPath + L"res\\" + atlasFile);
byteArray terrainBuf(terrainFile.length());
FileInputStream stream(terrainFile);
stream.read(terrainBuf);
return new BufferedImage(terrainBuf.data, terrainBuf.length);
}
void AbstractTexturePack::generateStitched(unordered_map<wstring, Icon*> texturesByName) {
app.DebugPrintf("Generating stitched texture based on map\n");
BufferedImage *atlas, *srcImg, *defaultAtlas; // I hate that they all need to have the star instead of the type getting it
Pixel *atlasPixels, *defaultPixels, *texPixels, *src, *dst;
int colCount, rowCount, resW, resH; // filled with hardcoded texture widths
if (texturesByName.find(L"sand") != texturesByName.end()) { // terrain.png
if (hasFile(L"res/terrain.png") || terrainAtlas.get() != nullptr)
return;
app.DebugPrintf("Generating terrain.png...\n");
defaultAtlas = getDefaultAtlas(L"terrain.png");
defaultPixels = reinterpret_cast<Pixel*>(defaultAtlas->getData());
colCount = 16;
rowCount = 32;
resW = colCount * texSize;
resH = rowCount * texSize;
terrainAtlas = std::make_unique<BufferedImage>(resW, resH, 0);
atlas = terrainAtlas.get();
atlasPixels = reinterpret_cast<Pixel*>(atlas->getData());
for (auto &i : texturesByName) {
auto preStitched = static_cast<StitchedTexture*>(i.second);
int x = preStitched->getU0() * resW;
int y = preStitched->getV0() * resH;
int width = (preStitched->getU1() * resW) - x;
int height = (preStitched->getV1() * resH) - y;
if (i.first.find(L"bed_") == 0)
srcImg = getBedTex(i.first);
else
srcImg = getImageResource(L"assets/minecraft/textures/block/" + i.first + L".png", true, false);
if (srcImg == nullptr || srcImg->getWidth() < 0 || srcImg->getHeight() < 0){
app.DebugPrintf("Failed to find %ls in resource pack!\n", i.first.c_str());
srcImg = grabFromDefault(i, defaultPixels, { defaultAtlas->getWidth(), defaultAtlas->getHeight() });
//__debugbreak();
//continue;
}
int imgW = srcImg->getWidth();
int imgH = srcImg->getHeight();
if (imgW != texSize || imgH != texSize) {
if (imgH % texSize == 0) {
app.DebugPrintf("Texture %ls is animated! using first frame\n", i.first.c_str());
srcImg = srcImg->getSubimage(0, 0, texSize, texSize);
imgW = imgH = texSize;
}
else {
app.DebugPrintf("Texture %ls is wrong size! skipping\n", i.first.c_str());
delete srcImg;
srcImg = grabFromDefault(i, defaultPixels, { defaultAtlas->getWidth(), defaultAtlas->getHeight() });
imgW = srcImg->getWidth();
imgH = srcImg->getHeight();
}
}
texPixels = reinterpret_cast<Pixel*>(srcImg->getData());
for (int j = 0; j < imgH * imgW; j++) {
Pixel* src = &texPixels[j];
Pixel* dst = &atlasPixels[(x + j % imgW) + (resW * (y + j / imgH))];
//unsigned char tmp = src->r; // unblue everything for saving, unsure why they are flipped
//src->r = src->b;
//src->b = tmp;
dst->raw = src->raw;
}
delete srcImg;
}
delete defaultAtlas;
// Uncomment these two lines and the unblue section above if you are debugging autostitching of the atlas!
// If you forget to uncomment the unblue section the written atlas will have red and blue swapped!
//D3DXIMAGE_INFO info = { resW, resH };
//RenderManager.SaveTextureData("autostitch.png", &info, atlas->getData());
} else { // items.png?
if (hasFile(L"res/items.png") || itemAtlas.get() != nullptr)
return;
defaultAtlas = getDefaultAtlas(L"items.png");
defaultPixels = reinterpret_cast<Pixel*>(defaultAtlas->getData());
colCount = rowCount = 16;
resW = colCount * texSize;
resH = rowCount * texSize;
itemAtlas = std::make_unique<BufferedImage>(resW, resH, 0);
atlas = itemAtlas.get();
atlasPixels = reinterpret_cast<Pixel*>(atlas->getData());
for (auto& i : texturesByName) {
auto preStitched = static_cast<StitchedTexture*>(i.second);
int x = preStitched->getU0() * resW;
int y = preStitched->getV0() * resH;
int width = (preStitched->getU1() * resW) - x;
int height = (preStitched->getV1() * resH) - y;
srcImg = getImageResource(L"assets/minecraft/textures/item/" + i.first + L".png", true, false);
if (srcImg == nullptr || srcImg->getWidth() < 0 || srcImg->getHeight() < 0) {
app.DebugPrintf("Failed to find %ls in resource pack!\n", i.first.c_str());
srcImg = grabFromDefault(i, defaultPixels, { defaultAtlas->getWidth(), defaultAtlas->getHeight() });
//__debugbreak();
//continue;
}
int imgW = srcImg->getWidth();
int imgH = srcImg->getHeight();
if (imgW != texSize || imgH != texSize) {
if (imgH % texSize == 0) {
app.DebugPrintf("Texture %ls is animated! using first frame\n", i.first.c_str());
srcImg = srcImg->getSubimage(0, 0, texSize, texSize);
imgW = imgH = texSize;
}
else {
app.DebugPrintf("Texture %ls is wrong size! skipping\n", i.first.c_str());
delete srcImg;
srcImg = grabFromDefault(i, defaultPixels, { defaultAtlas->getWidth(), defaultAtlas->getHeight() });
imgW = srcImg->getWidth();
imgH = srcImg->getHeight();
}
}
texPixels = reinterpret_cast<Pixel*>(srcImg->getData());
for (int j = 0; j < imgH * imgW; j++) {
Pixel* src = &texPixels[j];
Pixel* dst = &atlasPixels[(x + j % imgW) + (resW * (y + j / imgH))];
//unsigned char tmp = src->r; // unblue everything for saving, unsure why they are flipped
//src->r = src->b;
//src->b = tmp;
dst->raw = src->raw;
}
delete srcImg;
}
delete defaultAtlas;
// Uncomment these two lines and the unblue section above if you are debugging autostitching of the atlas!
// If you forget to uncomment the unblue section the written atlas will have red and blue swapped!
//D3DXIMAGE_INFO info = {resW, resH};
//RenderManager.SaveTextureData("autostitchitem.png", &info, atlas->getData());
}
}
BufferedImage *AbstractTexturePack::getImageResource(const wstring& File, bool filenameHasExtension /*= false*/, bool bTitleUpdateTexture /*=false*/, const wstring &drive /*=L""*/)
{
const char *pchTexture=wstringtofilename(File);
app.DebugPrintf("AbstractTexturePack::getImageResource - %s, drive is %s\n",pchTexture, wstringtofilename(drive));
std::string pchTexture=wstringtofilename(File);
app.DebugPrintf("AbstractTexturePack::getImageResource - %s, drive is %s\n", pchTexture.c_str(), wstringtofilename(drive).c_str());
return new BufferedImage(TexturePack::getResource(L"/" + File),filenameHasExtension,bTitleUpdateTexture,drive);
}
@ -236,12 +973,12 @@ void AbstractTexturePack::loadDefaultUI()
// Load new skin
const DWORD LOCATOR_SIZE = 256; // Use this to allocate space to hold a ResourceLocator string
WCHAR szResourceLocator[ LOCATOR_SIZE ];
WCHAR szResourceLocator[LOCATOR_SIZE];
swprintf(szResourceLocator, LOCATOR_SIZE, L"section://%X,%ls#%ls", c_ModuleHandle, L"media", L"media/skin_Minecraft.xur");
swprintf(szResourceLocator, LOCATOR_SIZE,L"section://%X,%ls#%ls",c_ModuleHandle,L"media", L"media/skin_Minecraft.xur");
XuiFreeVisuals(L"");
app.LoadSkin(szResourceLocator,nullptr);//L"TexturePack");
app.LoadSkin(szResourceLocator, nullptr);//L"TexturePack");
//CXuiSceneBase::GetInstance()->SetVisualPrefix(L"TexturePack");
CXuiSceneBase::GetInstance()->SkinChanged(CXuiSceneBase::GetInstance()->m_hObj);
#else
@ -260,25 +997,25 @@ void AbstractTexturePack::loadDefaultColourTable()
// Load the file
#ifdef __PS3__
// need to check if it's a BD build, so pass in the name
File coloursFile(AbstractTexturePack::getPath(true,app.GetBootedFromDiscPatch()?"colours.col":nullptr).append(L"res/colours.col"));
File coloursFile(AbstractTexturePack::getPath(true, app.GetBootedFromDiscPatch() ? "colours.col" : nullptr).append(L"res/colours.col"));
#else
File coloursFile(AbstractTexturePack::getPath(true).append(L"res/colours.col"));
#endif
if(coloursFile.exists())
if (coloursFile.exists())
{
DWORD dwLength = coloursFile.length();
byteArray data(static_cast<unsigned int>(dwLength));
FileInputStream fis(coloursFile);
fis.read(data,0,dwLength);
fis.read(data, 0, dwLength);
fis.close();
if(m_colourTable != nullptr) delete m_colourTable;
if (m_colourTable != nullptr) delete m_colourTable;
m_colourTable = new ColourTable(data.data, dwLength);
delete [] data.data;
delete[] data.data;
}
else
{
@ -294,36 +1031,36 @@ void AbstractTexturePack::loadDefaultHTMLColourTable()
const ULONG_PTR c_ModuleHandle = (ULONG_PTR)GetModuleHandle(nullptr);
const DWORD LOCATOR_SIZE = 256; // Use this to allocate space to hold a ResourceLocator string
WCHAR szResourceLocator[ LOCATOR_SIZE ];
WCHAR szResourceLocator[LOCATOR_SIZE];
// Try and load the HTMLColours.col based off the common XML first, before the deprecated xuiscene_colourtable
wsprintfW(szResourceLocator,L"section://%X,%s#%s",c_ModuleHandle,L"media", L"media/HTMLColours.col");
BYTE *data;
wsprintfW(szResourceLocator, L"section://%X,%s#%s", c_ModuleHandle, L"media", L"media/HTMLColours.col");
BYTE* data;
UINT dataLength;
if(XuiResourceLoadAll(szResourceLocator, &data, &dataLength) == S_OK)
if (XuiResourceLoadAll(szResourceLocator, &data, &dataLength) == S_OK)
{
m_colourTable->loadColoursFromData(data,dataLength);
m_colourTable->loadColoursFromData(data, dataLength);
XuiFree(data);
}
else
{
wsprintfW(szResourceLocator,L"section://%X,%s#%s",c_ModuleHandle,L"media", L"media/");
wsprintfW(szResourceLocator, L"section://%X,%s#%s", c_ModuleHandle, L"media", L"media/");
HXUIOBJ hScene;
HRESULT hr = XuiSceneCreate(szResourceLocator,L"xuiscene_colourtable.xur", nullptr, &hScene);
HRESULT hr = XuiSceneCreate(szResourceLocator, L"xuiscene_colourtable.xur", nullptr, &hScene);
if(HRESULT_SUCCEEDED(hr))
if (HRESULT_SUCCEEDED(hr))
{
loadHTMLColourTableFromXuiScene(hScene);
}
}
#else
if(app.hasArchiveFile(L"HTMLColours.col"))
if (app.hasArchiveFile(L"HTMLColours.col"))
{
byteArray textColours = app.getArchiveFile(L"HTMLColours.col");
m_colourTable->loadColoursFromData(textColours.data,textColours.length);
m_colourTable->loadColoursFromData(textColours.data, textColours.length);
delete [] textColours.data;
delete[] textColours.data;
}
#endif
}
@ -334,11 +1071,11 @@ void AbstractTexturePack::loadHTMLColourTableFromXuiScene(HXUIOBJ hObj)
HXUIOBJ child;
HRESULT hr = XuiElementGetFirstChild(hObj, &child);
while(HRESULT_SUCCEEDED(hr) && child != nullptr)
while (HRESULT_SUCCEEDED(hr) && child != nullptr)
{
LPCWSTR childName;
XuiElementGetId(child,&childName);
m_colourTable->setColour(childName,XuiTextElementGetText(child));
XuiElementGetId(child, &childName);
m_colourTable->setColour(childName, XuiTextElementGetText(child));
//eMinecraftTextColours colourIndex = eTextColor_NONE;
//for(int i = 0; i < (int)eTextColor_MAX; i++)
@ -362,7 +1099,7 @@ void AbstractTexturePack::loadHTMLColourTableFromXuiScene(HXUIOBJ hObj)
void AbstractTexturePack::loadUI()
{
loadColourTable();
#ifdef _XBOX
CXuiSceneBase::GetInstance()->SkinChanged(CXuiSceneBase::GetInstance()->m_hObj);
#endif
@ -379,22 +1116,22 @@ wstring AbstractTexturePack::getXuiRootPath()
// Load new skin
const DWORD LOCATOR_SIZE = 256; // Use this to allocate space to hold a ResourceLocator string
WCHAR szResourceLocator[ LOCATOR_SIZE ];
WCHAR szResourceLocator[LOCATOR_SIZE];
swprintf(szResourceLocator, LOCATOR_SIZE,L"section://%X,%ls#%ls",c_ModuleHandle,L"media", L"media/");
swprintf(szResourceLocator, LOCATOR_SIZE, L"section://%X,%ls#%ls", c_ModuleHandle, L"media", L"media/");
return szResourceLocator;
}
PBYTE AbstractTexturePack::getPackIcon(DWORD &dwImageBytes)
PBYTE AbstractTexturePack::getPackIcon(DWORD& dwImageBytes)
{
if(m_iconSize == 0 || m_iconData == nullptr) loadIcon();
if (m_iconSize == 0 || m_iconData == nullptr) loadIcon();
dwImageBytes = m_iconSize;
return m_iconData;
}
PBYTE AbstractTexturePack::getPackComparison(DWORD &dwImageBytes)
PBYTE AbstractTexturePack::getPackComparison(DWORD& dwImageBytes)
{
if(m_comparisonSize == 0 || m_comparisonData == nullptr) loadComparison();
if (m_comparisonSize == 0 || m_comparisonData == nullptr) loadComparison();
dwImageBytes = m_comparisonSize;
return m_comparisonData;

View file

@ -1,15 +1,19 @@
#pragma once
using namespace std;
#include <cstdint>
#include "TexturePack.h"
class BufferedImage;
union Pixel;
class AbstractTexturePack : public TexturePack
{
public:
static const unordered_map<std::wstring, std::wstring> INDEXED_TO_JAVA_MAP;
private:
const DWORD id;
const wstring name;
int texSize;
protected:
File *file;
@ -28,9 +32,10 @@ protected:
TexturePack *fallback;
ColourTable *m_colourTable;
protected:
BufferedImage *iconImage;
std::unique_ptr<BufferedImage> terrainAtlas, itemAtlas, bedTexCache;
BufferedImage* AbstractTexturePack::grabFromDefault(pair<wstring, Icon*> item, Pixel* ogAtlas, pair<int, int> ogDimensions);
private:
int textureId;
@ -46,6 +51,7 @@ protected:
virtual void loadComparison();
virtual void loadDescription();
virtual void loadName();
void checkTexSize();
public:
virtual InputStream *getResource(const wstring &name, bool allowFallback); //throws IOException
@ -66,8 +72,9 @@ public:
virtual wstring getDesc1();
virtual wstring getDesc2();
virtual wstring getWorldName();
virtual wstring getAnimationString(const wstring &textureName, const wstring &path, bool allowFallback);
BufferedImage* AbstractTexturePack::getBedTex(std::wstring name);
virtual void generateStitched(unordered_map<wstring, Icon*> texturesByName);
protected:
virtual wstring getAnimationString(const wstring &textureName, const wstring &path);

View file

@ -160,15 +160,15 @@ BufferedImage::BufferedImage(const wstring& File, bool filenameHasExtension /*=f
name = wDrive + L"res" + filePath.substr(0,filePath.length()-4) + mipMapPath + L".png";
}
const char *pchTextureName=wstringtofilename(name);
auto pchTextureName=wstringtofilename(name);
#ifndef _CONTENT_PACKAGE
app.DebugPrintf("\n--- Loading TEXTURE - %s\n\n",pchTextureName);
app.DebugPrintf("\n--- Loading TEXTURE - %s\n\n",pchTextureName.c_str());
#endif
D3DXIMAGE_INFO ImageInfo;
ZeroMemory(&ImageInfo,sizeof(D3DXIMAGE_INFO));
hr=RenderManager.LoadTextureData(pchTextureName,&ImageInfo,&data[l]);
hr=RenderManager.LoadTextureData(pchTextureName.c_str(), &ImageInfo, &data[l]);
if(hr!=ERROR_SUCCESS)

View file

@ -1,9 +1,20 @@
#pragma once
#include <cstdint>
using namespace std;
class Graphics;
class DLCPack;
union Pixel { // Could be a duplicate but I didnt search that hard
uint32_t raw;
struct { // argb flipped because of endianness
unsigned char b;
unsigned char g;
unsigned char r;
unsigned char a;
};
};
class BufferedImage
{
private:

View file

@ -35,6 +35,7 @@ target_include_directories(Minecraft.Client PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/Iggy/include"
"${CMAKE_SOURCE_DIR}/include/"
"${CMAKE_CURRENT_SOURCE_DIR}/Common/libs/bit7z/include"
)
target_compile_definitions(Minecraft.Client PRIVATE
${MINECRAFT_SHARED_DEFINES}
@ -60,11 +61,13 @@ target_link_libraries(Minecraft.Client PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Input_d.lib"
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Storage_d.lib"
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Render_PC_d.lib"
"${CMAKE_CURRENT_SOURCE_DIR}/Common/libs/bit7z/lib/x64/Debug/bit7z.lib"
>
$<$<NOT:$<CONFIG:Debug>>: # Release 4J libraries
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Input.lib"
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Storage.lib"
"${CMAKE_CURRENT_SOURCE_DIR}/${PLATFORM_NAME}/4JLibs/libs/4J_Render_PC.lib"
"${CMAKE_CURRENT_SOURCE_DIR}/Common/libs/bit7z/lib/x64/Release/bit7z.lib"
>
)

View file

@ -588,9 +588,9 @@ int LevelGenerationOptions::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD
nullptr // Unsupported
);
#else
const char *pchFilename=wstringtofilename(grf.getPath());
std::string pchFilename=wstringtofilename(grf.getPath());
HANDLE fileHandle = CreateFile(
pchFilename, // file name
pchFilename.c_str(), // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
nullptr, // Unused
@ -640,9 +640,9 @@ int LevelGenerationOptions::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD
nullptr // Unsupported
);
#else
const char *pchFilename=wstringtofilename(save.getPath());
auto pchFilename=wstringtofilename(save.getPath());
HANDLE fileHandle = CreateFile(
pchFilename, // file name
pchFilename.c_str(), // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
nullptr, // Unused

View file

@ -261,9 +261,9 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft *minecraft, LPVOID lpParame
nullptr // Unsupported
);
#else
const char *pchFilename=wstringtofilename(grf.getPath());
std::string pchFilename=wstringtofilename(grf.getPath());
HANDLE fileHandle = CreateFile(
pchFilename, // file name
pchFilename.c_str(), // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
nullptr, // Unused

View file

@ -0,0 +1,25 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BIT7Z_HPP
#define BIT7Z_HPP
#include "bitarchiveeditor.hpp"
#include "bitarchivereader.hpp"
#include "bitarchivewriter.hpp"
#include "bitexception.hpp"
#include "bitfilecompressor.hpp"
#include "bitfileextractor.hpp"
#include "bitmemcompressor.hpp"
#include "bitmemextractor.hpp"
#include "bitstreamcompressor.hpp"
#include "bitstreamextractor.hpp"
#endif // BIT7Z_HPP

View file

@ -0,0 +1,101 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BIT7ZLIBRARY_HPP
#define BIT7ZLIBRARY_HPP
#include <string>
#include "bitformat.hpp"
#include "bittypes.hpp"
#include "bitwindows.hpp"
//! @cond IGNORE_BLOCK_IN_DOXYGEN
struct IInArchive;
struct IOutArchive;
template< typename T >
class CMyComPtr;
//! @endcond
/**
* @brief The main namespace of the bit7z library.
*/
namespace bit7z {
/**
* @brief The default file path for the 7-zip shared library to be used by bit7z
* in case the user doesn't pass a path to the constructor of the Bit7zLibrary class.
*
* @note On Windows, the default library is 7z.dll, and it is searched following the Win32 API rules
* (https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order).
*
* @note On Linux, the default library is the absolute path to the "7z.so" installed by p7zip.
*
* @note In all other cases, the value will be the relative path to a "7z.so" in the working directory of the program.
*/
#ifdef __DOXYGEN__
constexpr auto kDefaultLibrary = "<platform-dependent value>";
#elif defined( _WIN32 )
constexpr auto kDefaultLibrary = BIT7Z_STRING( "7z.dll" );
#elif defined( __linux__ )
constexpr auto kDefaultLibrary = "/usr/lib/p7zip/7z.so"; // Default installation path of the p7zip shared library.
#else
constexpr auto kDefaultLibrary = "./7z.so";
#endif
/**
* @brief The Bit7zLibrary class allows accessing the basic functionalities provided by the 7z DLLs.
*/
class Bit7zLibrary final {
public:
Bit7zLibrary( const Bit7zLibrary& ) = delete;
Bit7zLibrary( Bit7zLibrary&& ) = delete;
auto operator=( const Bit7zLibrary& ) -> Bit7zLibrary& = delete;
auto operator=( Bit7zLibrary&& ) -> Bit7zLibrary& = delete;
/**
* @brief Constructs a Bit7zLibrary object by loading the specified 7zip shared library.
*
* By default, it searches a 7z.dll in the same path of the application.
*
* @param libraryPath the path to the shared library file to be loaded.
*/
explicit Bit7zLibrary( const tstring& libraryPath = kDefaultLibrary );
/**
* @brief Destructs the Bit7zLibrary object, freeing the loaded shared library.
*/
~Bit7zLibrary();
/**
* @brief Set the 7-zip shared library to use large memory pages.
*/
void setLargePageMode();
private:
HMODULE mLibrary;
FARPROC mCreateObjectFunc;
BIT7Z_NODISCARD
auto initInArchive( const BitInFormat& format ) const -> CMyComPtr< IInArchive >;
BIT7Z_NODISCARD
auto initOutArchive( const BitInOutFormat& format ) const -> CMyComPtr< IOutArchive >;
friend class BitInputArchive;
friend class BitOutputArchive;
};
} // namespace bit7z
#endif // BIT7ZLIBRARY_HPP

View file

@ -0,0 +1,305 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITABSTRACTARCHIVECREATOR_HPP
#define BITABSTRACTARCHIVECREATOR_HPP
#include <map>
#include <memory>
#include "bitabstractarchivehandler.hpp"
#include "bitcompressionlevel.hpp"
#include "bitcompressionmethod.hpp"
#include "bitformat.hpp"
#include "bitinputarchive.hpp"
struct IOutStream;
struct ISequentialOutStream;
namespace bit7z {
using std::ostream;
class ArchiveProperties;
/**
* @brief Enumeration representing how an archive creator should deal when the output archive already exists.
*/
enum struct UpdateMode {
None, ///< The creator will throw an exception (unless the OverwriteMode is not None).
Append, ///< The creator will append the new items to the existing archive.
Update, ///< New items whose path already exists in the archive will overwrite the old ones, other will be appended.
BIT7Z_DEPRECATED_ENUMERATOR( Overwrite, Update, "Since v4.0; please use the UpdateMode::Update enumerator." ) ///< @deprecated since v4.0; please use the UpdateMode::Update enumerator.
};
/**
* @brief Abstract class representing a generic archive creator.
*/
class BitAbstractArchiveCreator : public BitAbstractArchiveHandler {
public:
BitAbstractArchiveCreator( const BitAbstractArchiveCreator& ) = delete;
BitAbstractArchiveCreator( BitAbstractArchiveCreator&& ) = delete;
auto operator=( const BitAbstractArchiveCreator& ) -> BitAbstractArchiveCreator& = delete;
auto operator=( BitAbstractArchiveCreator&& ) -> BitAbstractArchiveCreator& = delete;
~BitAbstractArchiveCreator() override = default;
/**
* @return the format used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto format() const noexcept -> const BitInFormat& override;
/**
* @return the format used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto compressionFormat() const noexcept -> const BitInOutFormat&;
/**
* @return whether the creator crypts also the headers of archives or not.
*/
BIT7Z_NODISCARD auto cryptHeaders() const noexcept -> bool;
/**
* @return the compression level used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto compressionLevel() const noexcept -> BitCompressionLevel;
/**
* @return the compression method used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto compressionMethod() const noexcept -> BitCompressionMethod;
/**
* @return the dictionary size used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto dictionarySize() const noexcept -> uint32_t;
/**
* @return the word size used for creating/updating an archive.
*/
BIT7Z_NODISCARD auto wordSize() const noexcept -> uint32_t;
/**
* @return whether the archive creator uses solid compression or not.
*/
BIT7Z_NODISCARD auto solidMode() const noexcept -> bool;
/**
* @return the update mode used when updating existing archives.
*/
BIT7Z_NODISCARD auto updateMode() const noexcept -> UpdateMode;
/**
* @return the volume size (in bytes) used when creating multi-volume archives
* (a 0 value means that all files are going in a single archive).
*/
BIT7Z_NODISCARD auto volumeSize() const noexcept -> uint64_t;
/**
* @return the number of threads used when creating/updating an archive
* (a 0 value means that it will use the 7-zip default value).
*/
BIT7Z_NODISCARD auto threadsCount() const noexcept -> uint32_t;
/**
* @return whether the archive creator stores symbolic links as links in the output archive.
*/
BIT7Z_NODISCARD auto storeSymbolicLinks() const noexcept -> bool;
/**
* @brief Sets up a password for the output archives.
*
* When setting a password, the produced archives will be encrypted using the default
* cryptographic method of the output format. The option "crypt headers" remains unchanged,
* in contrast with what happens when calling the setPassword(tstring, bool) method.
*
* @note Calling setPassword when the output format doesn't support archive encryption
* (e.g., GZip, BZip2, etc...) does not have any effects (in other words, it doesn't
* throw exceptions, and it has no effects on compression operations).
*
* @note After a password has been set, it will be used for every subsequent operation.
* To disable the use of the password, you need to call the clearPassword method
* (inherited from BitAbstractArchiveHandler), which is equivalent to setPassword(L"").
*
* @param password the password to be used when creating/updating archives.
*/
void setPassword( const tstring& password ) override;
/**
* @brief Sets up a password for the output archive.
*
* When setting a password, the produced archive will be encrypted using the default
* cryptographic method of the output format. If the format is 7z, and the option
* "cryptHeaders" is set to true, the headers of the archive will be encrypted,
* resulting in a password request every time the output file will be opened.
*
* @note Calling setPassword when the output format doesn't support archive encryption
* (e.g., GZip, BZip2, etc...) does not have any effects (in other words, it doesn't
* throw exceptions, and it has no effects on compression operations).
*
* @note Calling setPassword with "cryptHeaders" set to true does not have effects on
* formats different from 7z.
*
* @note After a password has been set, it will be used for every subsequent operation.
* To disable the use of the password, you need to call the clearPassword method
* (inherited from BitAbstractArchiveHandler), which is equivalent to setPassword(L"").
*
* @param password the password to be used when creating/updating archives.
* @param cryptHeaders if true, the headers of the output archives will be encrypted
* (valid only when using the 7z format).
*/
void setPassword( const tstring& password, bool cryptHeaders );
/**
* @brief Sets the compression level to be used when creating/updating an archive.
*
* @param level the compression level desired.
*/
void setCompressionLevel( BitCompressionLevel level ) noexcept;
/**
* @brief Sets the compression method to be used when creating/updating an archive.
*
* @param method the compression method desired.
*/
void setCompressionMethod( BitCompressionMethod method );
/**
* @brief Sets the dictionary size to be used when creating/updating an archive.
*
* @param dictionarySize the dictionary size desired.
*/
void setDictionarySize( uint32_t dictionarySize );
/**
* @brief Sets the word size to be used when creating/updating an archive.
*
* @param wordSize the word size desired.
*/
void setWordSize( uint32_t wordSize );
/**
* @brief Sets whether to use solid compression or not.
*
* @note Setting the solid compression mode to true has effect only when using the 7z format with multiple
* input files.
*
* @param solidMode if true, it will be used the "solid compression" method.
*/
void setSolidMode( bool solidMode ) noexcept;
/**
* @brief Sets whether and how the creator can update existing archives or not.
*
* @note If set to UpdateMode::None, a subsequent compression operation may throw an exception
* if it targets an existing archive.
*
* @param mode the desired update mode.
*/
virtual void setUpdateMode( UpdateMode mode );
/**
* @brief Sets whether the creator can update existing archives or not.
*
* @deprecated since v4.0; it is provided just for an easier transition from the old v3 API.
*
* @note If set to false, a subsequent compression operation may throw an exception
* if it targets an existing archive.
*
* @param canUpdate if true, compressing operations will update existing archives.
*/
BIT7Z_DEPRECATED_MSG( "Since v4.0; please use the overloaded function that takes an UpdateMode enumerator." )
void setUpdateMode( bool canUpdate );
/**
* @brief Sets the volumeSize (in bytes) of the output archive volumes.
*
* @note This setting has effects only when the destination archive is on the filesystem.
*
* @param volumeSize The dimension of a volume.
*/
void setVolumeSize( uint64_t volumeSize ) noexcept;
/**
* @brief Sets the number of threads to be used when creating/updating an archive.
*
* @param threadsCount the number of threads desired.
*/
void setThreadsCount( uint32_t threadsCount ) noexcept;
/**
* @brief Sets whether the creator will store symbolic links as links in the output archive.
*
* @param storeSymlinks if true, symbolic links will be stored as links.
*/
void setStoreSymbolicLinks( bool storeSymlinks ) noexcept;
/**
* @brief Sets a property for the output archive format as described by the 7-zip documentation
* (e.g., https://sevenzip.osdn.jp/chm/cmdline/switches/method.htm).
*
* @tparam T An integral type (i.e., a bool or an integer type).
*
* @param name The string name of the property to be set.
* @param value The value to be used for the property.
*/
template< std::size_t N, typename T, typename = typename std::enable_if< std::is_integral< T >::value >::type >
void setFormatProperty( const wchar_t (&name)[N], T value ) noexcept { // NOLINT(*-avoid-c-arrays)
mExtraProperties[ name ] = value;
}
/**
* @brief Sets a property for the output archive format as described by the 7-zip documentation
* (e.g., https://sevenzip.osdn.jp/chm/cmdline/switches/method.htm).
*
* For example, passing the string L"tm" with a false value while creating a .7z archive
* will disable storing the last modified timestamps of the compressed files.
*
* @tparam T A non-integral type (i.e., a string).
*
* @param name The string name of the property to be set.
* @param value The value to be used for the property.
*/
template< std::size_t N, typename T, typename = typename std::enable_if< !std::is_integral< T >::value >::type >
void setFormatProperty( const wchar_t (&name)[N], const T& value ) noexcept { // NOLINT(*-avoid-c-arrays)
mExtraProperties[ name ] = value;
}
protected:
BitAbstractArchiveCreator( const Bit7zLibrary& lib,
const BitInOutFormat& format,
tstring password = {},
UpdateMode updateMode = UpdateMode::None );
BIT7Z_NODISCARD auto archiveProperties() const -> ArchiveProperties;
friend class BitOutputArchive;
private:
const BitInOutFormat& mFormat;
UpdateMode mUpdateMode;
BitCompressionLevel mCompressionLevel;
BitCompressionMethod mCompressionMethod;
uint32_t mDictionarySize;
uint32_t mWordSize;
bool mCryptHeaders;
bool mSolidMode;
uint64_t mVolumeSize;
uint32_t mThreadsCount;
bool mStoreSymbolicLinks;
std::map< std::wstring, BitPropVariant > mExtraProperties;
};
} // namespace bit7z
#endif // BITABSTRACTARCHIVECREATOR_HPP

View file

@ -0,0 +1,249 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITABSTRACTARCHIVEHANDLER_HPP
#define BITABSTRACTARCHIVEHANDLER_HPP
#include <cstdint>
#include <functional>
#include "bit7zlibrary.hpp"
#include "bitdefines.hpp"
namespace bit7z {
class BitInFormat;
/**
* @brief A std::function whose argument is the total size of the ongoing operation.
*/
using TotalCallback = std::function< void( uint64_t ) >;
/**
* @brief A std::function whose argument is the currently processed size of the ongoing operation and returns
* true or false whether the operation must continue or not.
*/
using ProgressCallback = std::function< bool( uint64_t ) >;
/**
* @brief A std::function whose arguments are the current processed input size, and the current output size of the
* ongoing operation.
*/
using RatioCallback = std::function< void( uint64_t, uint64_t ) >;
/**
* @brief A std::function whose argument is the path, in the archive, of the file currently being processed
* by the ongoing operation.
*/
using FileCallback = std::function< void( tstring ) >;
/**
* @brief A std::function returning the password to be used to handle an archive.
*/
using PasswordCallback = std::function< tstring() >;
/**
* @brief Enumeration representing how a handler should deal when an output file already exists.
*/
enum struct OverwriteMode {
None = 0, ///< The handler will throw an exception if the output file or buffer already exists.
Overwrite, ///< The handler will overwrite the old file or buffer with the new one.
Skip, ///< The handler will skip writing to the output file or buffer.
//TODO: RenameOutput,
//TODO: RenameExisting
};
/**
* @brief Enumeration representing the policy according to which the archive handler should treat
* the items that match the pattern given by the user.
*/
enum struct FilterPolicy {
Include, ///< Extract/compress the items that match the pattern.
Exclude ///< Do not extract/compress the items that match the pattern.
};
/**
* @brief Abstract class representing a generic archive handler.
*/
class BitAbstractArchiveHandler {
public:
BitAbstractArchiveHandler( const BitAbstractArchiveHandler& ) = delete;
BitAbstractArchiveHandler( BitAbstractArchiveHandler&& ) = delete;
auto operator=( const BitAbstractArchiveHandler& ) -> BitAbstractArchiveHandler& = delete;
auto operator=( BitAbstractArchiveHandler&& ) -> BitAbstractArchiveHandler& = delete;
virtual ~BitAbstractArchiveHandler() = default;
/**
* @return the Bit7zLibrary object used by the handler.
*/
BIT7Z_NODISCARD auto library() const noexcept -> const Bit7zLibrary&;
/**
* @return the format used by the handler for extracting or compressing.
*/
BIT7Z_NODISCARD virtual auto format() const -> const BitInFormat& = 0;
/**
* @return the password used to open, extract, or encrypt the archive.
*/
BIT7Z_NODISCARD auto password() const -> tstring;
/**
* @return a boolean value indicating whether the directory structure must be preserved while extracting
* or compressing the archive.
*/
BIT7Z_NODISCARD auto retainDirectories() const noexcept -> bool;
/**
* @return a boolean value indicating whether a password is defined or not.
*/
BIT7Z_NODISCARD auto isPasswordDefined() const noexcept -> bool;
/**
* @return the current total callback.
*/
BIT7Z_NODISCARD auto totalCallback() const -> TotalCallback;
/**
* @return the current progress callback.
*/
BIT7Z_NODISCARD auto progressCallback() const -> ProgressCallback;
/**
* @return the current ratio callback.
*/
BIT7Z_NODISCARD auto ratioCallback() const -> RatioCallback;
/**
* @return the current file callback.
*/
BIT7Z_NODISCARD auto fileCallback() const -> FileCallback;
/**
* @return the current password callback.
*/
BIT7Z_NODISCARD auto passwordCallback() const -> PasswordCallback;
/**
* @return the current OverwriteMode.
*/
BIT7Z_NODISCARD auto overwriteMode() const -> OverwriteMode;
/**
* @brief Sets up a password to be used by the archive handler.
*
* The password will be used to encrypt/decrypt archives by using the default
* cryptographic method of the archive format.
*
* @note Calling setPassword when the input archive is not encrypted does not have any effect on
* the extraction process.
*
* @note Calling setPassword when the output format doesn't support archive encryption
* (e.g., GZip, BZip2, etc...) does not have any effects (in other words, it doesn't
* throw exceptions, and it has no effects on compression operations).
*
* @note After a password has been set, it will be used for every subsequent operation.
* To disable the use of the password, you need to call the clearPassword method, which is equivalent
* to calling setPassword(L"").
*
* @param password the password to be used.
*/
virtual void setPassword( const tstring& password );
/**
* @brief Clear the current password used by the handler.
*
* Calling clearPassword() will disable the encryption/decryption of archives.
*
* @note This is equivalent to calling setPassword(L"").
*/
void clearPassword() noexcept;
/**
* @brief Sets whether the operations' output will preserve the input's directory structure or not.
*
* @param retain the setting for preserving or not the input directory structure
*/
void setRetainDirectories( bool retain ) noexcept;
/**
* @brief Sets the function to be called when the total size of an operation is available.
*
* @param callback the total callback to be used.
*/
void setTotalCallback( const TotalCallback& callback );
/**
* @brief Sets the function to be called when the processed size of the ongoing operation is updated.
*
* @note The completion percentage of the current operation can be obtained by calculating
* `static_cast<int>((100.0 * processed_size) / total_size)`.
*
* @param callback the progress callback to be used.
*/
void setProgressCallback( const ProgressCallback& callback );
/**
* @brief Sets the function to be called when the input processed size and current output size of the
* ongoing operation are known.
*
* @note The ratio percentage of a compression operation can be obtained by calculating
* `static_cast<int>((100.0 * output_size) / input_size)`.
*
* @param callback the ratio callback to be used.
*/
void setRatioCallback( const RatioCallback& callback );
/**
* @brief Sets the function to be called when the current file being processed changes.
*
* @param callback the file callback to be used.
*/
void setFileCallback( const FileCallback& callback );
/**
* @brief Sets the function to be called when a password is needed to complete the ongoing operation.
*
* @param callback the password callback to be used.
*/
void setPasswordCallback( const PasswordCallback& callback );
/**
* @brief Sets how the handler should behave when it tries to output to an existing file or buffer.
*
* @param mode the OverwriteMode to be used by the handler.
*/
void setOverwriteMode( OverwriteMode mode );
protected:
explicit BitAbstractArchiveHandler( const Bit7zLibrary& lib,
tstring password = {},
OverwriteMode overwriteMode = OverwriteMode::None );
private:
const Bit7zLibrary& mLibrary;
tstring mPassword;
bool mRetainDirectories;
OverwriteMode mOverwriteMode;
//CALLBACKS
TotalCallback mTotalCallback;
ProgressCallback mProgressCallback;
RatioCallback mRatioCallback;
FileCallback mFileCallback;
PasswordCallback mPasswordCallback;
};
} // namespace bit7z
#endif // BITABSTRACTARCHIVEHANDLER_HPP

View file

@ -0,0 +1,59 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITABSTRACTARCHIVEOPENER_HPP
#define BITABSTRACTARCHIVEOPENER_HPP
#include <vector>
#include <map>
#include "bitabstractarchivehandler.hpp"
#include "bitformat.hpp"
namespace bit7z {
using std::ostream;
/**
* @brief The BitAbstractArchiveOpener abstract class represents a generic archive opener.
*/
class BitAbstractArchiveOpener : public BitAbstractArchiveHandler {
public:
BitAbstractArchiveOpener( const BitAbstractArchiveOpener& ) = delete;
BitAbstractArchiveOpener( BitAbstractArchiveOpener&& ) = delete;
auto operator=( const BitAbstractArchiveOpener& ) -> BitAbstractArchiveOpener& = delete;
auto operator=( BitAbstractArchiveOpener&& ) -> BitAbstractArchiveOpener& = delete;
~BitAbstractArchiveOpener() override = default;
/**
* @return the archive format used by the archive opener.
*/
BIT7Z_NODISCARD auto format() const noexcept -> const BitInFormat& override;
/**
* @return the archive format used by the archive opener.
*/
BIT7Z_NODISCARD auto extractionFormat() const noexcept -> const BitInFormat&;
protected:
BitAbstractArchiveOpener( const Bit7zLibrary& lib,
const BitInFormat& format,
const tstring& password = {} );
private:
const BitInFormat& mFormat;
};
} // namespace bit7z
#endif // BITABSTRACTARCHIVEOPENER_HPP

View file

@ -0,0 +1,200 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEEDITOR_HPP
#define BITARCHIVEEDITOR_HPP
#include <unordered_map>
#include "bitarchivewriter.hpp"
namespace bit7z {
using std::vector;
using EditedItems = std::unordered_map< uint32_t, BitItemsVector::value_type >;
enum struct DeletePolicy : std::uint8_t {
ItemOnly,
RecurseDirs
};
/**
* @brief The BitArchiveEditor class allows creating new file archives or updating old ones.
* Update operations supported are the addition of new items,
* as well as renaming/updating/deleting old items;
*
* @note Changes are applied to the archive only after calling the applyChanges() method.
*/
class BIT7Z_MAYBE_UNUSED BitArchiveEditor final : public BitArchiveWriter {
public:
/**
* @brief Constructs a BitArchiveEditor object, reading the given archive file path.
*
* @param lib the 7z library to use.
* @param inFile the path to an input archive file.
* @param format the input/output archive format.
* @param password (optional) the password needed to read the input archive.
*/
BitArchiveEditor( const Bit7zLibrary& lib,
const tstring& inFile,
const BitInOutFormat& format,
const tstring& password = {} );
BitArchiveEditor( const BitArchiveEditor& ) = delete;
BitArchiveEditor( BitArchiveEditor&& ) = delete;
auto operator=( const BitArchiveEditor& ) -> BitArchiveEditor& = delete;
auto operator=( BitArchiveEditor&& ) -> BitArchiveEditor& = delete;
~BitArchiveEditor() override;
/**
* @brief Sets how the editor performs the update of the items in the archive.
*
* @note BitArchiveEditor doesn't support UpdateMode::None.
*
* @param mode the desired update mode (either UpdateMode::Append or UpdateMode::Overwrite).
*/
void setUpdateMode( UpdateMode mode ) override;
/**
* @brief Requests to change the path of the item at the specified index with the given one.
*
* @param index the index of the item to be renamed.
* @param newPath the new path (in the archive) desired for the item.
*/
void renameItem( uint32_t index, const tstring& newPath );
/**
* @brief Requests to change the path of the item from oldPath to the newPath.
*
* @param oldPath the old path (in the archive) of the item to be renamed.
* @param newPath the new path (in the archive) desired for the item.
*/
void renameItem( const tstring& oldPath, const tstring& newPath );
/**
* @brief Requests to update the content of the item at the specified index
* with the data from the given file.
*
* @param index the index of the item to be updated.
* @param inFile the path to the file containing the new data for the item.
*/
void updateItem( uint32_t index, const tstring& inFile );
/**
* @brief Requests to update the content of the item at the specified index
* with the data from the given buffer.
*
* @param index the index of the item to be updated.
* @param inBuffer the buffer containing the new data for the item.
*/
void updateItem( uint32_t index, const std::vector< byte_t >& inBuffer );
/**
* @brief Requests to update the content of the item at the specified index
* with the data from the given stream.
*
* @param index the index of the item to be updated.
* @param inStream the stream of new data for the item.
*/
void updateItem( uint32_t index, std::istream& inStream );
/**
* @brief Requests to update the content of the item at the specified path
* with the data from the given file.
*
* @param itemPath the path (in the archive) of the item to be updated.
* @param inFile the path to the file containing the new data for the item.
*/
void updateItem( const tstring& itemPath, const tstring& inFile );
/**
* @brief Requests to update the content of the item at the specified path
* with the data from the given buffer.
*
* @param itemPath the path (in the archive) of the item to be updated.
* @param inBuffer the buffer containing the new data for the item.
*/
void updateItem( const tstring& itemPath, const std::vector< byte_t >& inBuffer );
/**
* @brief Requests to update the content of the item at the specified path
* with the data from the given stream.
*
* @param itemPath the path (in the archive) of the item to be updated.
* @param inStream the stream of new data for the item.
*/
void updateItem( const tstring& itemPath, istream& inStream );
/**
* @brief Marks as deleted the item at the given index.
*
* @note By default, if the item is a folder, only its metadata is deleted, not the files within it.
* If instead the policy is set to DeletePolicy::RecurseDirs,
* then the items within the folder will also be deleted.
*
* @param index the index of the item to be deleted.
* @param policy the policy to be used when deleting items.
*
* @throws BitException if the index is invalid.
*/
void deleteItem( uint32_t index, DeletePolicy policy = DeletePolicy::ItemOnly );
/**
* @brief Marks as deleted the archive's item(s) with the specified path.
*
* @note By default, if the marked item is a folder, only its metadata will be deleted, not the files within it.
* To delete the folder contents as well, set the `policy` to `DeletePolicy::RecurseDirs`.
*
* @note The specified path must not begin with a path separator.
*
* @note A path with a trailing separator will _only_ be considered if
* the policy is DeletePolicy::RecurseDirs, and will only match folders;
* with DeletePolicy::ItemOnly, no item will match a path with a trailing separator.
*
* @note Generally, archives may contain multiple items with the same paths.
* If this is the case, all matching items will be marked as deleted according to the specified policy.
*
* @param itemPath the path (in the archive) of the item to be deleted.
* @param policy the policy to be used when deleting items.
*
* @throws BitException if the specified path is empty or invalid, or if no matching item could be found.
*/
void deleteItem( const tstring& itemPath, DeletePolicy policy = DeletePolicy::ItemOnly );
/**
* @brief Applies the requested changes (i.e., rename/update/delete operations) to the input archive.
*/
void applyChanges();
private:
EditedItems mEditedItems;
auto findItem( const tstring& itemPath ) -> uint32_t;
void checkIndex( uint32_t index );
auto itemProperty( InputIndex index, BitProperty property ) const -> BitPropVariant override;
auto itemStream( InputIndex index, ISequentialInStream** inStream ) const -> HRESULT override;
auto hasNewData( uint32_t index ) const noexcept -> bool override;
auto hasNewProperties( uint32_t index ) const noexcept -> bool override;
void markItemAsDeleted( uint32_t index );
};
} // namespace bit7z
#endif //BITARCHIVEEDITOR_HPP

View file

@ -0,0 +1,112 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEITEM_HPP
#define BITARCHIVEITEM_HPP
#include "bitgenericitem.hpp"
namespace bit7z {
/**
* The BitArchiveItem class represents a generic item inside an archive.
*/
class BitArchiveItem : public BitGenericItem {
public:
/**
* @return the index of the item in the archive.
*/
BIT7Z_NODISCARD auto index() const noexcept -> uint32_t;
/**
* @return true if and only if the item is a directory (i.e., it has the property BitProperty::IsDir).
*/
BIT7Z_NODISCARD auto isDir() const -> bool override;
/**
* @return true if and only if the item is a symbolic link (either has a non-empty BitProperty::SymLink,
* or it has POSIX/Win32 symbolic link file attributes).
*/
BIT7Z_NODISCARD auto isSymLink() const -> bool override;
/**
* @return the item's name; if not available, it tries to get it from the element's path or,
* if not possible, it returns an empty string.
*/
BIT7Z_NODISCARD auto name() const -> tstring override;
/**
* @return the extension of the item, if available or if it can be inferred from the name;
* otherwise it returns an empty string (e.g., when the item is a folder).
*/
BIT7Z_NODISCARD auto extension() const -> tstring;
/**
* @return the path of the item in the archive, if available or inferable from the name, or an empty string
* otherwise.
*/
BIT7Z_NODISCARD auto path() const -> tstring override;
/**
* @note Same as path(), but returning a native string (i.e., std::wstring on Windows, std::string elsewhere).
*
* @return the path of the item in the archive, if available or inferable from the name, or an empty string
* otherwise.
*/
BIT7Z_NODISCARD auto nativePath() const -> native_string;
/**
* @return the uncompressed size of the item.
*/
BIT7Z_NODISCARD auto size() const -> uint64_t override;
/**
* @return the item creation time.
*/
BIT7Z_NODISCARD auto creationTime() const -> time_type;
/**
* @return the item last access time.
*/
BIT7Z_NODISCARD auto lastAccessTime() const -> time_type;
/**
* @return the item last write time.
*/
BIT7Z_NODISCARD auto lastWriteTime() const -> time_type;
/**
* @return the item attributes.
*/
BIT7Z_NODISCARD auto attributes() const -> uint32_t override;
/**
* @return the compressed size of the item.
*/
BIT7Z_NODISCARD auto packSize() const -> uint64_t;
/**
* @return the CRC value of the item.
*/
BIT7Z_NODISCARD auto crc() const -> uint32_t;
/**
* @return true if and only if the item is encrypted.
*/
BIT7Z_NODISCARD auto isEncrypted() const -> bool;
protected:
uint32_t mItemIndex; //Note: it is not const since the subclass BitArchiveItemOffset can increment it!
explicit BitArchiveItem( uint32_t itemIndex ) noexcept;
};
} // namespace bit7z
#endif // BITARCHIVEITEM_HPP

View file

@ -0,0 +1,54 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEITEMINFO_HPP
#define BITARCHIVEITEMINFO_HPP
#include <map>
#include "bitarchiveitem.hpp"
namespace bit7z {
using std::wstring;
using std::map;
/**
* @brief The BitArchiveItemInfo class represents an archived item and that stores all its properties for later use.
*/
class BitArchiveItemInfo final : public BitArchiveItem {
public:
/**
* @brief Gets the specified item property.
*
* @param property the property to be retrieved.
*
* @return the value of the item property, if available, or an empty BitPropVariant.
*/
BIT7Z_NODISCARD auto itemProperty( BitProperty property ) const -> BitPropVariant override;
/**
* @return a map of all the available (i.e., non-empty) item properties and their respective values.
*/
BIT7Z_NODISCARD auto itemProperties() const -> map< BitProperty, BitPropVariant >;
private:
map< BitProperty, BitPropVariant > mItemProperties;
/* BitArchiveItem objects can be created and updated only by BitArchiveReader */
explicit BitArchiveItemInfo( uint32_t itemIndex );
void setProperty( BitProperty property, const BitPropVariant& value );
friend class BitArchiveReader;
};
} // namespace bit7z
#endif // BITARCHIVEITEMINFO_HPP

View file

@ -0,0 +1,53 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEITEMOFFSET_HPP
#define BITARCHIVEITEMOFFSET_HPP
#include "bitarchiveitem.hpp"
namespace bit7z {
class BitInputArchive;
/**
* @brief The BitArchiveItemOffset class represents an archived item but doesn't store its properties.
*/
class BitArchiveItemOffset final : public BitArchiveItem {
public:
auto operator++() noexcept -> BitArchiveItemOffset&;
auto operator++( int ) noexcept -> BitArchiveItemOffset; // NOLINT(cert-dcl21-cpp)
auto operator==( const BitArchiveItemOffset& other ) const noexcept -> bool;
auto operator!=( const BitArchiveItemOffset& other ) const noexcept -> bool;
/**
* @brief Gets the specified item property.
*
* @param property the property to be retrieved.
*
* @return the value of the item property, if available, or an empty BitPropVariant.
*/
BIT7Z_NODISCARD auto itemProperty( BitProperty property ) const -> BitPropVariant override;
private:
/* Note: a pointer, instead of a reference, allows this class, and hence BitInputArchive::ConstIterator,
* to be CopyConstructible so that stl algorithms can be used with ConstIterator! */
const BitInputArchive* mArc;
BitArchiveItemOffset( uint32_t itemIndex, const BitInputArchive& inputArchive ) noexcept;
friend class BitInputArchive;
};
} // namespace bit7z
#endif // BITARCHIVEITEMOFFSET_HPP

View file

@ -0,0 +1,277 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEREADER_HPP
#define BITARCHIVEREADER_HPP
#include "bitabstractarchiveopener.hpp"
#include "bitarchiveiteminfo.hpp"
#include "bitexception.hpp"
#include "bitinputarchive.hpp"
struct IInArchive;
struct IOutArchive;
struct IArchiveExtractCallback;
namespace bit7z {
/**
* @brief The BitArchiveReader class allows reading metadata of archives, as well as extracting them.
*/
class BitArchiveReader final : public BitAbstractArchiveOpener, public BitInputArchive {
public:
/**
* @brief Constructs a BitArchiveReader object, opening the input file archive.
*
* @note When bit7z is compiled using the `BIT7Z_AUTO_FORMAT` option, the format
* argument has the default value BitFormat::Auto (automatic format detection of the input archive).
* On the contrary, when `BIT7Z_AUTO_FORMAT` is not defined (i.e., no auto format detection available),
* the format argument must be specified.
*
* @param lib the 7z library used.
* @param inArchive the path to the archive to be read.
* @param archiveStart whether to search for the archive's start throughout the entire file
* or only at the beginning.
* @param format the format of the input archive.
* @param password (optional) the password needed for opening the input archive.
*/
BitArchiveReader( const Bit7zLibrary& lib,
const tstring& inArchive,
ArchiveStartOffset archiveStart,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveReader object, opening the input file archive.
*
* @note When bit7z is compiled using the `BIT7Z_AUTO_FORMAT` option, the format
* argument has the default value BitFormat::Auto (automatic format detection of the input archive).
* On the contrary, when `BIT7Z_AUTO_FORMAT` is not defined (i.e., no auto format detection available),
* the format argument must be specified.
*
* @param lib the 7z library used.
* @param inArchive the path to the archive to be read.
* @param format the format of the input archive.
* @param password (optional) the password needed for opening the input archive.
*/
BitArchiveReader( const Bit7zLibrary& lib,
const tstring& inArchive,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveReader object, opening the archive in the input buffer.
*
* @note When bit7z is compiled using the `BIT7Z_AUTO_FORMAT` option, the format
* argument has the default value BitFormat::Auto (automatic format detection of the input archive).
* On the contrary, when `BIT7Z_AUTO_FORMAT` is not defined (i.e., no auto format detection available),
* the format argument must be specified.
*
* @param lib the 7z library used.
* @param inArchive the input buffer containing the archive to be read.
* @param archiveStart whether to search for the archive's start throughout the entire file
* or only at the beginning.
* @param format the format of the input archive.
* @param password (optional) the password needed for opening the input archive.
*/
BitArchiveReader( const Bit7zLibrary& lib,
const buffer_t& inArchive,
ArchiveStartOffset archiveStart,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveReader object, opening the archive in the input buffer.
*
* @note When bit7z is compiled using the `BIT7Z_AUTO_FORMAT` option, the format
* argument has the default value BitFormat::Auto (automatic format detection of the input archive).
* On the contrary, when `BIT7Z_AUTO_FORMAT` is not defined (i.e., no auto format detection available),
* the format argument must be specified.
*
* @param lib the 7z library used.
* @param inArchive the input buffer containing the archive to be read.
* @param format the format of the input archive.
* @param password (optional) the password needed for opening the input archive.
*/
BitArchiveReader( const Bit7zLibrary& lib,
const std::vector< byte_t >& inArchive,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveReader object, opening the archive from the standard input stream.
*
* @note When bit7z is compiled using the `BIT7Z_AUTO_FORMAT` option, the format
* argument has the default value BitFormat::Auto (automatic format detection of the input archive).
* On the contrary, when `BIT7Z_AUTO_FORMAT` is not defined (i.e., no auto format detection available),
* the format argument must be specified.
*
* @param lib the 7z library used.
* @param inArchive the standard input stream of the archive to be read.
* @param archiveStart whether to search for the archive's start throughout the entire file
* or only at the beginning.
* @param format the format of the input archive.
* @param password (optional) the password needed for opening the input archive.
*/
BitArchiveReader( const Bit7zLibrary& lib,
std::istream& inArchive,
ArchiveStartOffset archiveStart,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveReader object, opening the archive from the standard input stream.
*
* @note When bit7z is compiled using the `BIT7Z_AUTO_FORMAT` option, the format
* argument has the default value BitFormat::Auto (automatic format detection of the input archive).
* On the contrary, when `BIT7Z_AUTO_FORMAT` is not defined (i.e., no auto format detection available),
* the format argument must be specified.
*
* @param lib the 7z library used.
* @param inArchive the standard input stream of the archive to be read.
* @param format the format of the input archive.
* @param password (optional) the password needed for opening the input archive.
*/
BitArchiveReader( const Bit7zLibrary& lib,
std::istream& inArchive,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT,
const tstring& password = {} );
BitArchiveReader( const BitArchiveReader& ) = delete;
BitArchiveReader( BitArchiveReader&& ) = delete;
auto operator=( const BitArchiveReader& ) -> BitArchiveReader& = delete;
auto operator=( BitArchiveReader&& ) -> BitArchiveReader& = delete;
/**
* @brief BitArchiveReader destructor.
*
* @note It releases the input archive file.
*/
~BitArchiveReader() override = default;
/**
* @return a map of all the available (i.e., non-empty) archive properties and their respective values.
*/
BIT7Z_NODISCARD auto archiveProperties() const -> map< BitProperty, BitPropVariant >;
/**
* @return a vector of all the archive items as BitArchiveItem objects.
*/
BIT7Z_NODISCARD auto items() const -> vector< BitArchiveItemInfo >;
/**
* @return the number of folders contained in the archive.
*/
BIT7Z_NODISCARD auto foldersCount() const -> uint32_t;
/**
* @return the number of files contained in the archive.
*/
BIT7Z_NODISCARD auto filesCount() const -> uint32_t;
/**
* @return the total uncompressed size of the archive content.
*/
BIT7Z_NODISCARD auto size() const -> uint64_t;
/**
* @return the total compressed size of the archive content.
*/
BIT7Z_NODISCARD auto packSize() const -> uint64_t;
/**
* @return true if and only if the archive has at least one encrypted item.
*/
BIT7Z_NODISCARD auto hasEncryptedItems() const -> bool;
/**
* @return true if and only if the archive has only encrypted items.
*/
BIT7Z_NODISCARD auto isEncrypted() const -> bool;
/**
* @return the number of volumes composing the archive.
*/
BIT7Z_NODISCARD auto volumesCount() const -> uint32_t;
/**
* @return true if and only if the archive is composed by multiple volumes.
*/
BIT7Z_NODISCARD auto isMultiVolume() const -> bool;
/**
* @return true if and only if the archive was created using solid compression.
*/
BIT7Z_NODISCARD auto isSolid() const -> bool;
/**
* Checks if the given archive is header-encrypted or not.
*
* @tparam T The input type of the archive (i.e., file path, buffer, or standard stream).
*
* @param lib the 7z library used.
* @param inArchive the archive to be read.
* @param format the format of the input archive.
*
* @return true if and only if the archive has at least one encrypted item.
*/
template< typename T >
BIT7Z_NODISCARD
static auto isHeaderEncrypted( const Bit7zLibrary& lib,
T&& inArchive,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT ) -> bool {
try {
const BitArchiveReader reader{ lib, std::forward< T >( inArchive ), format };
return false;
} catch ( const BitException& ex ) {
return isOpenEncryptedError( ex.code() );
}
}
/**
* Checks if the given archive contains only encrypted items.
*
* @note A header-encrypted archive is also encrypted, but the contrary is not generally true.
*
* @note An archive might contain both plain and encrypted files; in this case, this function will
* return false.
*
* @tparam T The input type of the archive (i.e., file path, buffer, or standard stream).
*
* @param lib the 7z library used.
* @param inArchive the archive to be read.
* @param format the format of the input archive.
*
* @return true if and only if the archive has only encrypted items.
*/
template< typename T >
BIT7Z_NODISCARD
static auto isEncrypted( const Bit7zLibrary& lib,
T&& inArchive,
const BitInFormat& format BIT7Z_DEFAULT_FORMAT ) -> bool {
try {
const BitArchiveReader reader{ lib, std::forward< T >( inArchive ), format };
return reader.isEncrypted();
} catch ( const BitException& ex ) {
return isOpenEncryptedError( ex.code() );
}
}
private:
static auto isOpenEncryptedError( std::error_code error ) -> bool;
};
BIT7Z_DEPRECATED_TYPEDEF( BitArchiveInfo, BitArchiveReader, "Since v4.0; please use BitArchiveReader." );
} // namespace bit7z
#endif // BITARCHIVEREADER_HPP

View file

@ -0,0 +1,120 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITARCHIVEWRITER_HPP
#define BITARCHIVEWRITER_HPP
#include "bitoutputarchive.hpp"
namespace bit7z {
/**
* @brief The BitArchiveWriter class allows creating new archives or updating old ones with new items.
*/
class BitArchiveWriter : public BitAbstractArchiveCreator, public BitOutputArchive {
public:
/**
* @brief Constructs an empty BitArchiveWriter object that can write archives of the specified format.
*
* @param lib the 7z library to use.
* @param format the output archive format.
*/
BitArchiveWriter( const Bit7zLibrary& lib, const BitInOutFormat& format );
/**
* @brief Constructs a BitArchiveWriter object, reading the given archive file path.
*
* @param lib the 7z library to use.
* @param inArchive the path to an input archive file.
* @param startOffset whether to search for the archive's start throughout the entire file
* or only at the beginning.
* @param format the input/output archive format.
* @param password (optional) the password needed to read the input archive.
*/
BitArchiveWriter( const Bit7zLibrary& lib,
const tstring& inArchive,
ArchiveStartOffset startOffset,
const BitInOutFormat& format,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveWriter object, reading the given archive file path.
*
* @param lib the 7z library to use.
* @param inArchive the path to an input archive file.
* @param format the input/output archive format.
* @param password (optional) the password needed to read the input archive.
*/
BitArchiveWriter( const Bit7zLibrary& lib,
const tstring& inArchive,
const BitInOutFormat& format,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveWriter object, reading the archive in the given buffer.
*
* @param lib the 7z library to use.
* @param inArchive the buffer containing the input archive.
* @param startOffset whether to search for the archive's start throughout the entire file
* or only at the beginning.
* @param format the input/output archive format.
* @param password (optional) the password needed to read the input archive.
*/
BitArchiveWriter( const Bit7zLibrary& lib,
const buffer_t& inArchive,
ArchiveStartOffset startOffset,
const BitInOutFormat& format,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveWriter object, reading the archive in the given buffer.
*
* @param lib the 7z library to use.
* @param inArchive the buffer containing the input archive.
* @param format the input/output archive format.
* @param password (optional) the password needed to read the input archive.
*/
BitArchiveWriter( const Bit7zLibrary& lib,
const std::vector< byte_t >& inArchive,
const BitInOutFormat& format,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveWriter object, reading the archive from the given standard input stream.
*
* @param lib the 7z library to use.
* @param inArchive the standard stream of the input archive.
* @param startOffset whether to search for the archive's start throughout the entire file
* or only at the beginning.
* @param format the input/output archive format.
* @param password (optional) the password needed to read the input archive.
*/
BitArchiveWriter( const Bit7zLibrary& lib,
std::istream& inArchive,
ArchiveStartOffset startOffset,
const BitInOutFormat& format,
const tstring& password = {} );
/**
* @brief Constructs a BitArchiveWriter object, reading the archive from the given standard input stream.
*
* @param lib the 7z library to use.
* @param inArchive the standard stream of the input archive.
* @param format the input/output archive format.
* @param password (optional) the password needed to read the input archive.
*/
BitArchiveWriter( const Bit7zLibrary& lib,
std::istream& inArchive,
const BitInOutFormat& format,
const tstring& password = {} );
};
} // namespace bit7z
#endif //BITARCHIVEWRITER_HPP

View file

@ -0,0 +1,30 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITCOMPRESSIONLEVEL_HPP
#define BITCOMPRESSIONLEVEL_HPP
namespace bit7z {
/**
* @brief The BitCompressionLevel enum represents the compression level used by 7z when creating archives.
* @note It uses the same values used by [7-zip](https://sevenzip.osdn.jp/chm/cmdline/switches/method.htm#ZipX).
*/
enum struct BitCompressionLevel {
None = 0, ///< Copy mode (no compression)
Fastest = 1, ///< Fastest compressing
Fast = 3, ///< Fast compressing
Normal = 5, ///< Normal compressing
Max = 7, ///< Maximum compressing
Ultra = 9 ///< Ultra compressing
};
} // namespace bit7z
#endif // BITCOMPRESSIONLEVEL_HPP

View file

@ -0,0 +1,30 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITCOMPRESSIONMETHOD_HPP
#define BITCOMPRESSIONMETHOD_HPP
namespace bit7z {
/**
* @brief The BitCompressionMethod enum represents the compression methods used by 7z when creating archives.
*/
enum struct BitCompressionMethod {
Copy,
Deflate,
Deflate64,
BZip2,
Lzma,
Lzma2,
Ppmd
};
} // namespace bit7z
#endif // BITCOMPRESSIONMETHOD_HPP

View file

@ -0,0 +1,116 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITCOMPRESSOR_HPP
#define BITCOMPRESSOR_HPP
#include <vector>
#include "bitoutputarchive.hpp"
namespace bit7z {
using std::vector;
namespace filesystem { // NOLINT(modernize-concat-nested-namespaces)
namespace fsutil {
auto stem( const tstring& path ) -> tstring;
} // namespace fsutil
} // namespace filesystem
using namespace filesystem;
#ifdef __cpp_if_constexpr
#define BIT7Z_IF_CONSTEXPR if constexpr
#else
#define BIT7Z_IF_CONSTEXPR if
#endif
/**
* @brief The BitCompressor template class allows compressing files into archives.
*
* It let decide various properties of the produced archive file, such as the password
* protection and the compression level desired.
*/
template< typename Input >
class BitCompressor : public BitAbstractArchiveCreator {
public:
/**
* @brief Constructs a BitCompressor object.
*
* The Bit7zLibrary parameter is needed to have access to the functionalities
* of the 7z DLLs. On the contrary, the BitInOutFormat is required to know the
* format of the output archive.
*
* @param lib the 7z library to use.
* @param format the output archive format.
*/
BitCompressor( Bit7zLibrary const& lib, BitInOutFormat const& format )
: BitAbstractArchiveCreator( lib, format ) {}
/**
* @brief Compresses a single file.
*
* @param inFile the file to be compressed.
* @param outFile the path (relative or absolute) to the output archive file.
* @param inputName (optional) the name to give to the compressed file inside the output archive.
*/
void compressFile( Input inFile,
const tstring& outFile,
const tstring& inputName = {} ) const {
/* Note: if inFile is a filesystem path (i.e., its type is const tstring&), we can deduce the archived
* item filename using the original filename. Otherwise, if the user didn't specify the input file name,
* we use the filename (without extension) of the output file path. */
tstring name;
BIT7Z_IF_CONSTEXPR( !std::is_same< Input, const tstring& >::value ) {
name = inputName.empty() ? fsutil::stem( outFile ) : inputName;
}
BitOutputArchive outputArchive{ *this, outFile };
outputArchive.addFile( inFile, name );
outputArchive.compressTo( outFile );
}
/**
* @brief Compresses the input file to the output buffer.
*
* @param inFile the file to be compressed.
* @param outBuffer the buffer going to contain the output archive.
* @param inputName (optional) the name to give to the compressed file inside the output archive.
*/
void compressFile( Input inFile,
vector< byte_t >& outBuffer,
const tstring& inputName = {} ) const {
BitOutputArchive outputArchive{ *this, outBuffer };
outputArchive.addFile( inFile, inputName );
outputArchive.compressTo( outBuffer );
}
/**
* @brief Compresses the input file to the output stream.
*
* @param inFile the file to be compressed.
* @param outStream the output stream.
* @param inputName (optional) the name to give to the compressed file inside the output archive.
*/
void compressFile( Input inFile,
ostream& outStream,
const tstring& inputName = {} ) const {
BitOutputArchive outputArchive{ *this };
outputArchive.addFile( inFile, inputName );
outputArchive.compressTo( outStream );
}
};
} // namespace bit7z
#endif //BITCOMPRESSOR_HPP

View file

@ -0,0 +1,121 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITDEFINES_HPP
#define BITDEFINES_HPP
/* Uncomment the following macros if you don't want to define them yourself in your project files,
* and you can't enable them via CMake. */
//#define BIT7Z_AUTO_FORMAT
//#define BIT7Z_AUTO_PREFIX_LONG_PATHS
//#define BIT7Z_DISABLE_USE_STD_FILESYSTEM
//#define BIT7Z_REGEX_MATCHING
//#define BIT7Z_USE_STD_BYTE
//#define BIT7Z_USE_NATIVE_STRING
#if ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201703L ) || ( defined( __cplusplus ) && __cplusplus >= 201703L )
# define BIT7Z_CPP_STANDARD 17
#elif ( defined( _MSVC_LANG ) && _MSVC_LANG >= 201402L ) || ( defined( __cplusplus ) && __cplusplus >= 201402L )
# define BIT7Z_CPP_STANDARD 14
#else
# define BIT7Z_CPP_STANDARD 11
#endif
#ifndef BIT7Z_DISABLE_USE_STD_FILESYSTEM
# if defined( __cpp_lib_filesystem )
# define BIT7Z_USE_STANDARD_FILESYSTEM
# elif BIT7Z_CPP_STANDARD >= 17 && defined( __has_include )
# if __has_include( <filesystem> )
# define BIT7Z_USE_STANDARD_FILESYSTEM
# endif
# endif
#endif
/* Macro defines for [[nodiscard]] and [[maybe_unused]] attributes. */
#if defined( __has_cpp_attribute )
# if __has_cpp_attribute( nodiscard )
# define BIT7Z_NODISCARD [[nodiscard]]
# endif
# if __has_cpp_attribute( maybe_unused )
# define BIT7Z_MAYBE_UNUSED [[maybe_unused]]
# endif
# if __has_cpp_attribute( deprecated )
# define BIT7Z_DEPRECATED [[deprecated]]
# define BIT7Z_DEPRECATED_MSG( msg ) [[deprecated( msg )]]
# endif
#endif
/* The compiler doesn't support __has_cpp_attribute, but it is using the C++17 standard. */
#if !defined( BIT7Z_NODISCARD ) && BIT7Z_CPP_STANDARD >= 17
# define BIT7Z_NODISCARD [[nodiscard]]
#endif
#if !defined( BIT7Z_MAYBE_UNUSED ) && BIT7Z_CPP_STANDARD >= 17
# define BIT7Z_MAYBE_UNUSED [[maybe_unused]]
#endif
#if !defined( BIT7Z_DEPRECATED ) && BIT7Z_CPP_STANDARD >= 14
# define BIT7Z_DEPRECATED [[deprecated]]
# define BIT7Z_DEPRECATED_MSG( msg ) [[deprecated( msg )]]
#endif
/* Compiler is using at most the C++14 standard, so we use the compiler-specific attributes/defines were possible. */
#ifndef BIT7Z_NODISCARD
# if defined( __GNUC__ ) || defined(__clang__)
# define BIT7Z_NODISCARD __attribute__(( warn_unused_result ))
# elif defined( _Check_return_ ) // Old MSVC versions
# define BIT7Z_NODISCARD _Check_return_
# else
# define BIT7Z_NODISCARD
# endif
#endif
#ifndef BIT7Z_MAYBE_UNUSED
# if defined( __GNUC__ ) || defined(__clang__)
# define BIT7Z_MAYBE_UNUSED __attribute__(( unused ))
# else
# define BIT7Z_MAYBE_UNUSED
# endif
#endif
/* Compiler is using the C++11 standard, so we use the compiler-specific attributes were possible.
* Note: these macros are used in the public API, so we cannot assume that we are always using a C++14 compiler.*/
#ifndef BIT7Z_DEPRECATED
# if defined( __GNUC__ ) || defined( __clang__ )
# define BIT7Z_DEPRECATED __attribute__(( __deprecated__ ))
# define BIT7Z_DEPRECATED_MSG( msg ) __attribute__(( __deprecated__( msg ) ))
# elif defined( _MSC_VER )
# define BIT7Z_DEPRECATED __declspec( deprecated )
# define BIT7Z_DEPRECATED_MSG( msg ) __declspec( deprecated( msg ) )
# else
# define BIT7Z_DEPRECATED
# define BIT7Z_DEPRECATED_MSG( msg )
# endif
#endif
#ifndef BIT7Z_DEPRECATED_ENUMERATOR
// Before v6.0, GCC didn't support deprecating single enumerators.
# if defined( __GNUC__ ) && !defined( __clang__ ) && __GNUC__ < 6
# define BIT7Z_DEPRECATED_ENUMERATOR( deprecated_value, new_value, msg ) deprecated_value = new_value
# else
# define BIT7Z_DEPRECATED_ENUMERATOR( deprecated_value, new_value, msg ) \
deprecated_value BIT7Z_DEPRECATED_MSG( msg ) = new_value
# endif
#endif
#ifndef BIT7Z_DEPRECATED_TYPEDEF
# if defined( __GNUC__ ) && !defined( __clang__ ) && __GNUC__ < 7
# define BIT7Z_DEPRECATED_TYPEDEF( alias_name, alias_value, msg ) \
using alias_name BIT7Z_MAYBE_UNUSED __attribute__(( __deprecated__( msg ) )) = alias_value
# else
# define BIT7Z_DEPRECATED_TYPEDEF( alias_name, alias_value, msg ) \
using alias_name BIT7Z_MAYBE_UNUSED BIT7Z_DEPRECATED_MSG( msg ) = alias_value
# endif
#endif
#endif //BITDEFINES_HPP

View file

@ -0,0 +1,84 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITERROR_HPP
#define BITERROR_HPP
#include <system_error>
#include "bitdefines.hpp"
namespace bit7z {
/**
* @brief The BitError enum struct values represent bit7z specific errors.
*/
enum struct BitError {
Fail = 1,
FilterNotSpecified,
FormatFeatureNotSupported,
IndicesNotSpecified,
InvalidArchivePath,
InvalidOutputBufferSize,
InvalidCompressionMethod,
InvalidDictionarySize,
InvalidIndex,
InvalidWordSize,
ItemIsAFolder,
ItemMarkedAsDeleted,
NoMatchingItems,
NoMatchingSignature,
NonEmptyOutputBuffer,
NullOutputBuffer,
RequestedWrongVariantType,
UnsupportedOperation,
UnsupportedVariantType,
WrongUpdateMode,
InvalidZipPassword,
InvalidDirectoryPath,
ItemPathOutsideOutputDirectory,
ItemHasAbsolutePath
};
auto make_error_code( BitError error ) -> std::error_code;
/**
* @brief The BitFailureSource enum struct values represent bit7z error conditions.
* They can be used for performing queries on bit7z's `error_code`s, for the purpose
* of grouping, classification, or error translation.
*/
enum struct BitFailureSource {
CRCError,
DataAfterEnd,
DataError,
InvalidArchive,
InvalidArgument,
FormatDetectionError,
HeadersError,
NoSuchItem,
OperationNotSupported,
OperationNotPermitted,
UnavailableData,
UnexpectedEnd,
WrongPassword
};
auto make_error_condition( BitFailureSource failureSource ) -> std::error_condition;
} // namespace bit7z
namespace std {
template<>
struct BIT7Z_MAYBE_UNUSED is_error_code_enum< bit7z::BitError > : public true_type {};
template <>
struct BIT7Z_MAYBE_UNUSED is_error_condition_enum< bit7z::BitFailureSource > : public true_type {};
} // namespace std
#endif //BITERROR_HPP

View file

@ -0,0 +1,103 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITEXCEPTION_HPP
#define BITEXCEPTION_HPP
#include <vector>
#include <system_error>
#include "bitdefines.hpp"
#include "bittypes.hpp"
#include "bitwindows.hpp"
namespace bit7z {
using std::system_error;
using FailedFiles = std::vector< std::pair< tstring, std::error_code > >;
auto make_hresult_code( HRESULT res ) noexcept -> std::error_code;
auto last_error_code() noexcept -> std::error_code;
/**
* @brief The BitException class represents a generic exception thrown from the bit7z classes.
*/
class BitException final : public system_error {
public:
#ifdef _WIN32
using native_code_type = HRESULT;
#else
using native_code_type = int;
#endif
/**
* @brief Constructs a BitException object with the given message, and the specific files that failed.
*
* @param message the message associated with the exception object.
* @param files the vector of files that failed, with the corresponding error codes.
* @param code the HRESULT code associated with the exception object.
*/
explicit BitException( const char* message, std::error_code code, FailedFiles&& files = {} );
/**
* @brief Constructs a BitException object with the given message, and the specific file that failed.
*
* @param message the message associated with the exception object.
* @param code the HRESULT code associated with the exception object.
* @param file the file that failed during the operation.
*/
BitException( const char* message, std::error_code code, tstring&& file );
/**
* @brief Constructs a BitException object with the given message, and the specific file that failed.
*
* @param message the message associated with the exception object.
* @param code the HRESULT code associated with the exception object.
* @param file the file that failed during the operation.
*/
BitException( const char* message, std::error_code code, const tstring& file );
/**
* @brief Constructs a BitException object with the given message.
*
* @param message the message associated with the exception object.
* @param code the HRESULT code associated with the exception object.
*/
explicit BitException( const std::string& message, std::error_code code );
/**
* @return the native error code (e.g., HRESULT on Windows, int elsewhere)
* corresponding to the exception's std::error_code.
*/
BIT7Z_NODISCARD auto nativeCode() const noexcept -> native_code_type;
/**
* @return the HRESULT error code corresponding to the exception's std::error_code.
*/
BIT7Z_NODISCARD auto hresultCode() const noexcept -> HRESULT;
/**
* @return the POSIX error code corresponding to the exception's std::error_code.
*/
BIT7Z_NODISCARD auto posixCode() const noexcept -> int;
/**
* @return the vector of files that caused the exception to be thrown, along with the corresponding
* error codes.
*/
BIT7Z_NODISCARD auto failedFiles() const noexcept -> const FailedFiles&;
private:
FailedFiles mFailedFiles;
};
} // namespace bit7z
#endif // BITEXCEPTION_HPP

View file

@ -0,0 +1,284 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITEXTRACTOR_HPP
#define BITEXTRACTOR_HPP
#include <algorithm>
#include "bitabstractarchiveopener.hpp"
#include "biterror.hpp"
#include "bitexception.hpp"
#include "bitinputarchive.hpp"
namespace bit7z {
namespace filesystem { // NOLINT(modernize-concat-nested-namespaces)
namespace fsutil {
auto wildcard_match( const tstring& pattern, const tstring& str ) -> bool;
} // namespace fsutil
} // namespace filesystem
/**
* @brief The BitExtractor template class allows extracting the content of archives from supported input types.
*
* @tparam Input the type of input archives that the generated extractor class supports.
*/
template< typename Input >
class BitExtractor final : public BitAbstractArchiveOpener {
public:
/**
* @brief Constructs a BitExtractor object.
*
* The Bit7zLibrary parameter is needed to have access to the functionalities
* of the 7z DLLs. On the contrary, the BitInFormat is required to know the
* format of the in_file archives.
*
* @note When bit7z is compiled using the BIT7Z_AUTO_FORMAT macro define, the format
* argument has the default value BitFormat::Auto (automatic format detection of the in_file archive).
* Otherwise, when BIT7Z_AUTO_FORMAT is not defined (i.e., no auto format detection available),
* the format argument must be specified.
*
* @param lib the 7z library to use.
* @param format the in_file archive format.
*/
explicit BitExtractor( const Bit7zLibrary& lib, const BitInFormat& format BIT7Z_DEFAULT_FORMAT )
: BitAbstractArchiveOpener( lib, format ) {}
/**
* @brief Extracts the given archive to the chosen directory.
*
* @param inArchive the input archive to be extracted.
* @param outDir the output directory where extracted files will be put.
*/
void extract( Input inArchive, const tstring& outDir = {} ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outDir );
}
/**
* @brief Extracts a file from the given archive to the output buffer.
*
* @param inArchive the input archive to extract from.
* @param outBuffer the output buffer where the content of the extracted file will be put.
* @param index the index of the file to be extracted from the archive.
*/
void extract( Input inArchive, vector< byte_t >& outBuffer, uint32_t index = 0 ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outBuffer, index );
}
/**
* @brief Extracts a file from the given archive to the output stream.
*
* @param inArchive the input archive to extract from.
* @param outStream the (binary) stream where the content of the extracted file will be put.
* @param index the index of the file to be extracted from the archive.
*/
void extract( Input inArchive, std::ostream& outStream, uint32_t index = 0 ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outStream, index );
}
/**
* @brief Extracts the content of the given archive into a map of memory buffers, where the keys are
* the paths of the files (inside the archive), and the values are their decompressed contents.
*
* @param inArchive the input archive to be extracted.
* @param outMap the output map.
*/
void extract( Input inArchive, std::map< tstring, vector< byte_t > >& outMap ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outMap );
}
/**
* @brief Extracts the files in the archive that match the given wildcard pattern to the chosen directory.
*
* @param inArchive the input archive to extract from.
* @param itemFilter the wildcard pattern used for matching the paths of files inside the archive.
* @param outDir the output directory where extracted files will be put.
* @param policy the filtering policy to be applied to the matched items.
*/
void extractMatching( Input inArchive,
const tstring& itemFilter,
const tstring& outDir = {},
FilterPolicy policy = FilterPolicy::Include ) const {
using namespace filesystem;
if ( itemFilter.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::FilterNotSpecified ) );
}
extractMatchingFilter( inArchive, outDir, policy, [ &itemFilter ]( const tstring& itemPath ) -> bool {
return fsutil::wildcard_match( itemFilter, itemPath );
} );
}
/**
* @brief Extracts to the output buffer the first file in the archive matching the given wildcard pattern.
*
* @param inArchive the input archive to extract from.
* @param itemFilter the wildcard pattern used for matching the paths of files inside the archive.
* @param outBuffer the output buffer where to extract the file.
* @param policy the filtering policy to be applied to the matched items.
*/
void extractMatching( Input inArchive,
const tstring& itemFilter,
vector< byte_t >& outBuffer,
FilterPolicy policy = FilterPolicy::Include ) const {
using namespace filesystem;
if ( itemFilter.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::FilterNotSpecified ) );
}
extractMatchingFilter( inArchive, outBuffer, policy,
[ &itemFilter ]( const tstring& itemPath ) -> bool {
return fsutil::wildcard_match( itemFilter, itemPath );
} );
}
/**
* @brief Extracts the specified items from the given archive to the chosen directory.
*
* @param inArchive the input archive to extract from.
* @param indices the indices of the files in the archive that should be extracted.
* @param outDir the output directory where the extracted files will be placed.
*/
void extractItems( Input inArchive,
const std::vector< uint32_t >& indices,
const tstring& outDir = {} ) const {
if ( indices.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::IndicesNotSpecified ) );
}
BitInputArchive inputArchive( *this, inArchive );
inputArchive.extractTo( outDir, indices );
}
#ifdef BIT7Z_REGEX_MATCHING
/**
* @brief Extracts the files in the archive that match the given regex pattern to the chosen directory.
*
* @note Available only when compiling bit7z using the BIT7Z_REGEX_MATCHING preprocessor define.
*
* @param inArchive the input archive to extract from.
* @param regex the regex used for matching the paths of files inside the archive.
* @param outDir the output directory where extracted files will be put.
* @param policy the filtering policy to be applied to the matched items.
*/
void extractMatchingRegex( Input inArchive,
const tstring& regex,
const tstring& outDir = {},
FilterPolicy policy = FilterPolicy::Include ) const {
if ( regex.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::FilterNotSpecified ) );
}
const tregex regexFilter( regex, tregex::ECMAScript | tregex::optimize );
extractMatchingFilter( inArchive, outDir, policy, [ &regexFilter ]( const tstring& itemPath ) -> bool {
return std::regex_match( itemPath, regexFilter );
} );
}
/**
* @brief Extracts the first file in the archive that matches the given regex pattern to the output buffer.
*
* @note Available only when compiling bit7z using the BIT7Z_REGEX_MATCHING preprocessor define.
*
* @param inArchive the input archive to extract from.
* @param regex the regex used for matching the paths of files inside the archive.
* @param outBuffer the output buffer where the extracted file will be put.
* @param policy the filtering policy to be applied to the matched items.
*/
void extractMatchingRegex( Input inArchive,
const tstring& regex,
vector< byte_t >& outBuffer,
FilterPolicy policy = FilterPolicy::Include ) const {
if ( regex.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::FilterNotSpecified ) );
}
const tregex regexFilter( regex, tregex::ECMAScript | tregex::optimize );
return extractMatchingFilter( inArchive, outBuffer, policy,
[ &regexFilter ]( const tstring& itemPath ) -> bool {
return std::regex_match( itemPath, regexFilter );
} );
}
#endif
/**
* @brief Tests the given archive without extracting its content.
*
* If the archive is not valid, a BitException is thrown!
*
* @param inArchive the input archive to be tested.
*/
void test( Input inArchive ) const {
BitInputArchive inputArchive( *this, inArchive );
inputArchive.test();
}
private:
void extractMatchingFilter( Input inArchive,
const tstring& outDir,
FilterPolicy policy,
const std::function< bool( const tstring& ) >& filter ) const {
BitInputArchive inputArchive( *this, inArchive );
vector< uint32_t > matchedIndices;
const bool shouldExtractMatchedItems = policy == FilterPolicy::Include;
// Searching for files inside the archive that match the given filter
for ( const auto& item : inputArchive ) {
const bool itemMatches = filter( item.path() );
if ( itemMatches == shouldExtractMatchedItems ) {
/* The if-condition is equivalent to an exclusive XNOR (negated XOR) between
* itemMatches and shouldExtractMatchedItems.
* In other words, it is true only if the current item either:
* - matches the filter, and we must include any matching item; or
* - doesn't match the filter, and we must exclude those that match. */
matchedIndices.push_back( item.index() );
}
}
if ( matchedIndices.empty() ) {
throw BitException( "Cannot extract items", make_error_code( BitError::NoMatchingItems ) );
}
inputArchive.extractTo( outDir, matchedIndices );
}
void extractMatchingFilter( Input inArchive,
vector< byte_t >& outBuffer,
FilterPolicy policy,
const std::function< bool( const tstring& ) >& filter ) const {
BitInputArchive inputArchive( *this, inArchive );
const bool shouldExtractMatchedItem = policy == FilterPolicy::Include;
// Searching for files inside the archive that match the given filter
for ( const auto& item : inputArchive ) {
const bool itemMatches = filter( item.path() );
if ( itemMatches == shouldExtractMatchedItem ) {
/* The if-condition is equivalent to an exclusive NOR (negated XOR) between
* itemMatches and shouldExtractMatchedItem. */
inputArchive.extractTo( outBuffer, item.index() );
return;
}
}
throw BitException( "Failed to extract items", make_error_code( BitError::NoMatchingItems ) );
}
};
} // namespace bit7z
#endif //BITEXTRACTOR_HPP

View file

@ -0,0 +1,150 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITFILECOMPRESSOR_HPP
#define BITFILECOMPRESSOR_HPP
#include <map>
#include <ostream>
#include <vector>
#include "bitcompressor.hpp"
namespace bit7z {
using std::vector;
using std::map;
using std::ostream;
using namespace filesystem;
/**
* @brief The BitFileCompressor class allows compressing files and directories.
* The compressed archives can be saved to the filesystem, standard streams, or memory buffers.
*
* It let decide various properties of the produced archive, such as the password
* protection and the compression level desired.
*/
class BitFileCompressor final : public BitCompressor< const tstring& > {
public:
/**
* @brief Constructs a BitFileCompressor object.
*
* The Bit7zLibrary parameter is needed to have access to the functionalities
* of the 7z DLLs. On the contrary, the BitInOutFormat is required to know the
* format of the output archive.
*
* @param lib the 7z library used.
* @param format the output archive format.
*/
BitFileCompressor( const Bit7zLibrary& lib, const BitInOutFormat& format );
/* Compression from the file system to the file system. */
/**
* @brief Compresses the given files or directories.
*
* The items in the first argument must be the relative or absolute paths to files or
* directories existing on the filesystem.
*
* @param inPaths a vector of paths.
* @param outFile the path (relative or absolute) to the output archive file.
*/
void compress( const std::vector< tstring >& inPaths, const tstring& outFile ) const;
/**
* @brief Compresses the given files or directories using the specified aliases.
*
* The items in the first argument must be the relative or absolute paths to files or
* directories existing on the filesystem.
* Each pair in the map must follow the following format:
* {"path to file in the filesystem", "alias path in the archive"}.
*
* @param inPaths a map of paths and corresponding aliases.
* @param outFile the path (relative or absolute) to the output archive file.
*/
void compress( const std::map< tstring, tstring >& inPaths, const tstring& outFile ) const;
/**
* @brief Compresses a group of files.
*
* @note Any path to a directory or to a not-existing file will be ignored!
*
* @param inFiles the path (relative or absolute) to the input files.
* @param outFile the path (relative or absolute) to the output archive file.
*/
void compressFiles( const std::vector< tstring >& inFiles, const tstring& outFile ) const;
/**
* @brief Compresses the files contained in a directory.
*
* @param inDir the path (relative or absolute) to the input directory.
* @param outFile the path (relative or absolute) to the output archive file.
* @param recursive (optional) if true, it searches files inside the sub-folders of inDir.
* @param filter (optional) the filter to use when searching files inside inDir.
*/
void compressFiles( const tstring& inDir,
const tstring& outFile,
bool recursive = true,
const tstring& filter = BIT7Z_STRING( "*" ) ) const;
/**
* @brief Compresses an entire directory.
*
* @note This method is equivalent to compressFiles with filter set to L"".
*
* @param inDir the path (relative or absolute) to the input directory.
* @param outFile the path (relative or absolute) to the output archive file.
*/
void compressDirectory( const tstring& inDir, const tstring& outFile ) const;
/**
* @brief Compresses the contents of a directory.
*
* @note Unlike compressFiles, this method includes also the metadata of the sub-folders.
*
* @param inDir the path (relative or absolute) to the input directory.
* @param outFile the path (relative or absolute) to the output archive file.
* @param recursive (optional) if true, it searches the contents inside the sub-folders of inDir.
* @param filter (optional) the filter to use when searching the contents inside inDir.
*/
void compressDirectoryContents( const tstring& inDir,
const tstring& outFile,
bool recursive = true,
const tstring& filter = BIT7Z_STRING( "*" ) ) const;
/* Compression from the file system to standard streams. */
/**
* @brief Compresses the given files or directories.
*
* The items in the first argument must be the relative or absolute paths to files or
* directories existing on the filesystem.
*
* @param inPaths a vector of paths.
* @param outStream the standard ostream where the archive will be output.
*/
void compress( const std::vector< tstring >& inPaths, std::ostream& outStream ) const;
/**
* @brief Compresses the given files or directories using the specified aliases.
*
* The items in the first argument must be the relative or absolute paths to files or
* directories existing on the filesystem.
* Each pair in the map must follow the following format:
* {"path to file in the filesystem", "alias path in the archive"}.
*
* @param inPaths a map of paths and corresponding aliases.
* @param outStream the standard ostream where to output the archive file.
*/
void compress( const std::map< tstring, tstring >& inPaths, std::ostream& outStream ) const;
};
} // namespace bit7z
#endif // BITFILECOMPRESSOR_HPP

View file

@ -0,0 +1,23 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITFILEEXTRACTOR_HPP
#define BITFILEEXTRACTOR_HPP
#include "bitextractor.hpp"
namespace bit7z {
/**
* @brief The BitFileExtractor alias allows extracting archives on the filesystem.
*/
using BitFileExtractor BIT7Z_MAYBE_UNUSED = BitExtractor< const tstring& >;
} // namespace bit7z
#endif // BITFILEEXTRACTOR_HPP

View file

@ -0,0 +1,254 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITFORMAT_HPP
#define BITFORMAT_HPP
#include <bitset>
#include <type_traits>
#include "bitcompressionmethod.hpp"
#include "bitdefines.hpp"
#include "bittypes.hpp"
namespace bit7z {
/**
* @brief The FormatFeatures enum specifies the features supported by an archive file format.
*/
enum struct FormatFeatures : unsigned {
MultipleFiles = 1u << 0, ///< The format can compress/extract multiple files (2^0 = 0000001)
SolidArchive = 1u << 1, ///< The format supports solid archives (2^1 = 0000010)
CompressionLevel = 1u << 2, ///< The format is able to use different compression levels (2^2 = 0000100)
Encryption = 1u << 3, ///< The format supports archive encryption (2^3 = 0001000)
HeaderEncryption = 1u << 4, ///< The format can encrypt the file names (2^4 = 0010000)
MultipleMethods = 1u << 5 ///< The format can use different compression methods (2^6 = 0100000)
};
template< typename Enum >
using underlying_type_t = typename std::underlying_type< Enum >::type;
template< typename Enum >
inline constexpr auto to_underlying( Enum enum_value ) noexcept -> underlying_type_t< Enum > {
return static_cast< underlying_type_t< Enum > >( enum_value );
}
inline constexpr auto operator|( FormatFeatures lhs, FormatFeatures rhs ) noexcept -> FormatFeatures {
return static_cast< FormatFeatures >( to_underlying( lhs ) | to_underlying( rhs ) );
}
using FormatFeaturesType = underlying_type_t< FormatFeatures >;
inline constexpr auto operator&( FormatFeatures lhs, FormatFeatures rhs ) noexcept -> FormatFeaturesType {
return to_underlying( lhs ) & to_underlying( rhs );
}
/**
* @brief The BitInFormat class specifies an extractable archive format.
*
* @note Usually, the user of the library should not create new formats and, instead,
* use the ones provided by the BitFormat namespace.
*/
class BitInFormat {
public:
//non-copyable
BitInFormat( const BitInFormat& other ) = delete;
auto operator=( const BitInFormat& other ) -> BitInFormat& = delete;
//non-movable
BitInFormat( BitInFormat&& other ) = delete;
auto operator=( BitInFormat&& other ) -> BitInFormat& = delete;
~BitInFormat() = default;
/**
* @brief Constructs a BitInFormat object with the ID value used by the 7z SDK.
* @param value the value of the format in the 7z SDK.
*/
constexpr explicit BitInFormat( unsigned char value ) noexcept: mValue( value ) {}
/**
* @return the value of the format in the 7z SDK.
*/
BIT7Z_NODISCARD auto value() const noexcept -> unsigned char;
/**
* @param other the target object to compare to.
* @return a boolean value indicating whether this format is equal to the "other" or not.
*/
auto operator==( BitInFormat const& other ) const noexcept -> bool;
/**
* @param other the target object to compare to.
* @return a boolean value indicating whether this format is different from the "other" or not.
*/
auto operator!=( BitInFormat const& other ) const noexcept -> bool;
private:
unsigned char mValue;
};
/**
* @brief The BitInOutFormat class specifies a format available for creating new archives and extract old ones.
*
* @note Usually, the user of the library should not create new formats and, instead,
* use the ones provided by the BitFormat namespace.
*/
class BitInOutFormat final : public BitInFormat {
public:
/**
* @brief Constructs a BitInOutFormat object with an ID value, an extension and a set of supported features.
*
* @param value the value of the format in the 7z SDK.
* @param ext the default file extension of the archive format.
* @param defaultMethod the default method used for compressing the archive format.
* @param features the set of features supported by the archive format
*/
constexpr BitInOutFormat( unsigned char value,
const tchar* ext,
BitCompressionMethod defaultMethod,
FormatFeatures features ) noexcept
: BitInFormat( value ), mExtension( ext ), mDefaultMethod( defaultMethod ), mFeatures( features ) {}
//non-copyable
BitInOutFormat( const BitInOutFormat& other ) = delete;
auto operator=( const BitInOutFormat& other ) -> BitInOutFormat& = delete;
//non-movable
BitInOutFormat( BitInOutFormat&& other ) = delete;
auto operator=( BitInOutFormat&& other ) -> BitInOutFormat& = delete;
~BitInOutFormat() = default;
/**
* @return the default file extension of the archive format.
*/
BIT7Z_NODISCARD
auto extension() const noexcept -> const tchar*;
/**
* @return the bitset of the features supported by the format.
*/
BIT7Z_NODISCARD
auto features() const noexcept -> FormatFeatures;
/**
* @brief Checks if the format has a specific feature (see FormatFeatures enum).
*
* @param feature feature to be checked.
*
* @return a boolean value indicating whether the format has the given feature.
*/
BIT7Z_NODISCARD
auto hasFeature( FormatFeatures feature ) const noexcept -> bool;
/**
* @return the default method used for compressing the archive format.
*/
BIT7Z_NODISCARD
auto defaultMethod() const noexcept -> BitCompressionMethod;
private:
const tchar* mExtension;
BitCompressionMethod mDefaultMethod;
FormatFeatures mFeatures;
};
/**
* @brief The namespace that contains a set of archive formats usable with bit7z classes.
*/
namespace BitFormat {
#ifdef BIT7Z_AUTO_FORMAT
/**
* @brief Automatic Format Detection (available only when compiling bit7z using the `BIT7Z_AUTO_FORMAT` option).
*/
extern const BitInFormat Auto;
#endif
extern const BitInFormat Rar; ///< RAR Archive Format
extern const BitInFormat Arj; ///< ARJ Archive Format
//NOLINTNEXTLINE(*-identifier-length)
extern const BitInFormat Z; ///< Z Archive Format
extern const BitInFormat Lzh; ///< LZH Archive Format
extern const BitInFormat Cab; ///< CAB Archive Format
extern const BitInFormat Nsis; ///< NSIS Archive Format
extern const BitInFormat Lzma; ///< LZMA Archive Format
extern const BitInFormat Lzma86; ///< LZMA86 Archive Format
extern const BitInFormat Ppmd; ///< PPMD Archive Format
extern const BitInFormat Zstd; ///< ZSTD Archive Format
extern const BitInFormat LVM; ///< LVM Archive Format
extern const BitInFormat AVB; ///< AVB Archive Format
extern const BitInFormat LP; ///< LP Archive Format
extern const BitInFormat Sparse; ///< Sparse Archive Format
extern const BitInFormat APFS; ///< APFS Archive Format
extern const BitInFormat Vhdx; ///< VHDX Archive Format
extern const BitInFormat COFF; ///< COFF Archive Format
extern const BitInFormat Ext; ///< EXT Archive Format
extern const BitInFormat VMDK; ///< VMDK Archive Format
extern const BitInFormat VDI; ///< VDI Archive Format
extern const BitInFormat QCow; ///< QCOW Archive Format
extern const BitInFormat GPT; ///< GPT Archive Format
extern const BitInFormat Rar5; ///< RAR5 Archive Format
extern const BitInFormat IHex; ///< IHEX Archive Format
extern const BitInFormat Hxs; ///< HXS Archive Format
//NOLINTNEXTLINE(*-identifier-length)
extern const BitInFormat TE; ///< TE Archive Format
extern const BitInFormat UEFIc; ///< UEFIc Archive Format
extern const BitInFormat UEFIs; ///< UEFIs Archive Format
extern const BitInFormat SquashFS; ///< SquashFS Archive Format
extern const BitInFormat CramFS; ///< CramFS Archive Format
extern const BitInFormat APM; ///< APM Archive Format
extern const BitInFormat Mslz; ///< MSLZ Archive Format
extern const BitInFormat Flv; ///< FLV Archive Format
extern const BitInFormat Swf; ///< SWF Archive Format
extern const BitInFormat Swfc; ///< SWFC Archive Format
extern const BitInFormat Ntfs; ///< NTFS Archive Format
extern const BitInFormat Fat; ///< FAT Archive Format
extern const BitInFormat Mbr; ///< MBR Archive Format
extern const BitInFormat Vhd; ///< VHD Archive Format
//NOLINTNEXTLINE(*-identifier-length)
extern const BitInFormat Pe; ///< PE Archive Format
extern const BitInFormat Elf; ///< ELF Archive Format
extern const BitInFormat Macho; ///< MACHO Archive Format
extern const BitInFormat Udf; ///< UDF Archive Format
extern const BitInFormat Xar; ///< XAR Archive Format
extern const BitInFormat Mub; ///< MUB Archive Format
extern const BitInFormat Hfs; ///< HFS Archive Format
extern const BitInFormat Dmg; ///< DMG Archive Format
extern const BitInFormat Compound; ///< COMPOUND Archive Format
extern const BitInFormat Iso; ///< ISO Archive Format
extern const BitInFormat Chm; ///< CHM Archive Format
extern const BitInFormat Split; ///< SPLIT Archive Format
extern const BitInFormat Rpm; ///< RPM Archive Format
extern const BitInFormat Deb; ///< DEB Archive Format
extern const BitInFormat Cpio; ///< CPIO Archive Format
extern const BitInOutFormat Zip; ///< ZIP Archive Format
extern const BitInOutFormat BZip2; ///< BZIP2 Archive Format
extern const BitInOutFormat SevenZip; ///< 7Z Archive Format
//NOLINTNEXTLINE(*-identifier-length)
extern const BitInOutFormat Xz; ///< XZ Archive Format
extern const BitInOutFormat Wim; ///< WIM Archive Format
extern const BitInOutFormat Tar; ///< TAR Archive Format
extern const BitInOutFormat GZip; ///< GZIP Archive Format
} // namespace BitFormat
#ifdef BIT7Z_AUTO_FORMAT
#define BIT7Z_DEFAULT_FORMAT = BitFormat::Auto
#else
#define BIT7Z_DEFAULT_FORMAT
#endif
} // namespace bit7z
#endif // BITFORMAT_HPP

View file

@ -0,0 +1,43 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITFS_HPP
#define BITFS_HPP
/* Header for forward declaring fs namespace. */
#include "bitdefines.hpp" /* For BIT7Z_USE_STANDARD_FILESYSTEM */
#ifdef BIT7Z_USE_STANDARD_FILESYSTEM
#include <filesystem>
#else
/* Notes: we use this forward declaration to avoid including private headers (e.g. fs.hpp).
* Since some public API headers include bitgenericitem.hpp (e.g. "bitoutputarchive.hpp"),
* including private headers here would result in the "leaking" out of these latter in the public API.*/
namespace ghc {
namespace filesystem {
class path;
} // namespace filesystem
} // namespace ghc
#endif
namespace bit7z {
namespace fs {
#ifdef BIT7Z_USE_STANDARD_FILESYSTEM
using namespace std::filesystem;
#else
using namespace ghc::filesystem;
#endif
} // namespace fs
} // namespace bit7z
#endif //BITFS_HPP

View file

@ -0,0 +1,66 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITGENERICITEM_HPP
#define BITGENERICITEM_HPP
#include "bitpropvariant.hpp"
namespace bit7z {
/**
* @brief The BitGenericItem interface class represents a generic item (either inside or outside an archive).
*/
class BitGenericItem {
public:
/**
* @return true if and only if the item is a directory (i.e., it has the property BitProperty::IsDir).
*/
BIT7Z_NODISCARD virtual auto isDir() const -> bool = 0;
/**
* @return true if and only if the item is a symbolic link.
*/
BIT7Z_NODISCARD virtual auto isSymLink() const -> bool = 0;
/**
* @return the uncompressed size of the item.
*/
BIT7Z_NODISCARD virtual auto size() const -> uint64_t = 0;
/**
* @return the name of the item, if available or inferable from the path, or an empty string otherwise.
*/
BIT7Z_NODISCARD virtual auto name() const -> tstring = 0;
/**
* @return the path of the item.
*/
BIT7Z_NODISCARD virtual auto path() const -> tstring = 0;
/**
* @return the item attributes.
*/
BIT7Z_NODISCARD virtual auto attributes() const -> uint32_t = 0;
/**
* @brief Gets the specified item property.
*
* @param property the property to be retrieved.
*
* @return the value of the item property, if available, or an empty BitPropVariant.
*/
BIT7Z_NODISCARD virtual auto itemProperty( BitProperty property ) const -> BitPropVariant = 0;
virtual ~BitGenericItem() = default;
};
} // namespace bit7z
#endif //BITGENERICITEM_HPP

View file

@ -0,0 +1,452 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITINPUTARCHIVE_HPP
#define BITINPUTARCHIVE_HPP
#include <array>
#include <map>
#include "bitabstractarchivehandler.hpp"
#include "bitarchiveitemoffset.hpp"
#include "bitformat.hpp"
#include "bitfs.hpp"
struct IInStream;
struct IInArchive;
struct IOutArchive;
namespace bit7z {
using std::vector;
/**
* @brief Offset from where the archive starts within the input file.
*/
enum struct ArchiveStartOffset : std::uint8_t {
None, ///< Don't specify an archive start offset. For some formats, like Zip archives,
///< this means that the whole input file will be searched for the archive's start.
FileStart ///< Check only the file start for the archive's start.
};
/**
* @brief The BitInputArchive class, given a handler object, allows reading/extracting the content of archives.
*/
class BitInputArchive {
public:
/**
* @brief Constructs a BitInputArchive object, opening the input file archive.
*
* @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
* be used for reading the input archive
* @param inFile the path to the input archive file
* @param startOffset (optional) specifies whether to search for the archive's start throughout the
* entire file or only at the beginning. The default behavior is to search at the beginning.
*/
BitInputArchive( const BitAbstractArchiveHandler& handler,
const tstring& inFile,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitInputArchive object, opening the input file archive.
*
* @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
* be used for reading the input archive
* @param arcPath the path to the input archive file
* @param startOffset (optional) whether to search for the archive's start throughout the entire file
* or only at the beginning. The default behavior is to search at the beginning.
*/
BitInputArchive( const BitAbstractArchiveHandler& handler,
const fs::path& arcPath,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitInputArchive object, opening the archive given in the input buffer.
*
* @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
* be used for reading the input archive
* @param inBuffer the buffer containing the input archive
* @param startOffset (optional) whether to search for the archive's start throughout the entire file
* or only at the beginning. The default behavior is to search at the beginning.
*/
BitInputArchive( const BitAbstractArchiveHandler& handler,
const buffer_t& inBuffer,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitInputArchive object, opening the archive by reading the given input stream.
*
* @param handler the reference to the BitAbstractArchiveHandler object containing all the settings to
* be used for reading the input archive
* @param inStream the standard input stream of the input archive
* @param startOffset (optional) whether to search for the archive's start throughout the entire file
* or only at the beginning. The default behavior is to search at the beginning.
*/
BitInputArchive( const BitAbstractArchiveHandler& handler,
std::istream& inStream,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
BitInputArchive( const BitInputArchive& ) = delete;
BitInputArchive( BitInputArchive&& ) = delete;
auto operator=( const BitInputArchive& ) -> BitInputArchive& = delete;
auto operator=( BitInputArchive&& ) -> BitInputArchive& = delete;
virtual ~BitInputArchive();
/**
* @return the detected format of the file.
*/
BIT7Z_NODISCARD auto detectedFormat() const noexcept -> const BitInFormat&;
/**
* @brief Gets the specified archive property.
*
* @param property the property to be retrieved.
*
* @return the current value of the archive property or an empty BitPropVariant if no value is specified.
*/
BIT7Z_NODISCARD auto archiveProperty( BitProperty property ) const -> BitPropVariant;
/**
* @brief Gets the specified property of an item in the archive.
*
* @param index the index (in the archive) of the item.
* @param property the property to be retrieved.
*
* @return the current value of the item property or an empty BitPropVariant if the item has no value for
* the property.
*/
BIT7Z_NODISCARD auto itemProperty( uint32_t index, BitProperty property ) const -> BitPropVariant;
/**
* @return the number of items contained in the archive.
*/
BIT7Z_NODISCARD auto itemsCount() const -> uint32_t;
/**
* @param index the index of an item in the archive.
*
* @return true if and only if the item at the given index is a folder.
*/
BIT7Z_NODISCARD auto isItemFolder( uint32_t index ) const -> bool;
/**
* @param index the index of an item in the archive.
*
* @return true if and only if the item at the given index is encrypted.
*/
BIT7Z_NODISCARD auto isItemEncrypted( uint32_t index ) const -> bool;
/**
* @return the path to the archive (the empty string for buffer/stream archives).
*/
BIT7Z_NODISCARD auto archivePath() const noexcept -> const tstring&;
/**
* @return the BitAbstractArchiveHandler object containing the settings for reading the archive.
*/
BIT7Z_NODISCARD auto handler() const noexcept -> const BitAbstractArchiveHandler&;
/**
* @brief Use the given format property to read the archive.
*
* @param name the name of the property.
* @param property the property value.
*/
void useFormatProperty( const wchar_t* name, const BitPropVariant& property ) const;
/**
* @brief Use the given format property to read the archive.
*
* @tparam T the type of the property.
* @param name the name of the property.
* @param value the property value.
*/
template< typename T,
typename = typename std::enable_if< is_explicitly_convertible< T, BitPropVariant >::value >::type >
void useFormatProperty( const wchar_t* name, T&& value ) const { // NOLINT(*-avoid-c-arrays)
useFormatProperty( name, BitPropVariant{ std::forward< T >( value ) } );
}
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( const tstring& outDir, const std::vector< uint32_t >& indices = {} ) const {
extractTo( outDir, indices );
}
/**
* @brief Extracts the archive to the chosen directory.
*
* @param outDir the output directory where the extracted files will be put.
*/
void extractTo( const tstring& outDir ) const;
/**
* @brief Extracts the specified items to the chosen directory.
*
* @param outDir the output directory where the extracted files will be put.
* @param indices the array of indices of the files in the archive that must be extracted.
*/
void extractTo( const tstring& outDir, const std::vector< uint32_t >& indices ) const;
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( std::vector< byte_t >& outBuffer, uint32_t index = 0 ) const {
extractTo( outBuffer, index );
}
/**
* @brief Extracts a file to the output buffer.
*
* @param outBuffer the output buffer where the content of the archive will be put.
* @param index the index of the file to be extracted.
*/
void extractTo( std::vector< byte_t >& outBuffer, uint32_t index = 0 ) const;
template< std::size_t N >
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
void extract( std::array< byte_t, N >& buffer, uint32_t index = 0 ) const {
extractTo( buffer.data(), buffer.size(), index );
}
/**
* @brief Extracts a file to the pre-allocated output buffer.
*
* @tparam N the size of the output buffer (it must be equal to the unpacked size
* of the item to be extracted).
* @param buffer the pre-allocated output buffer.
* @param index the index of the file to be extracted.
*/
template< std::size_t N >
void extractTo( std::array< byte_t, N >& buffer, uint32_t index = 0 ) const {
extractTo( buffer.data(), buffer.size(), index );
}
template< std::size_t N >
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
void extract( byte_t (& buffer)[N], uint32_t index = 0 ) const { // NOLINT(*-avoid-c-arrays)
extractTo( buffer, N, index );
}
/**
* @brief Extracts a file to the pre-allocated output buffer.
*
* @tparam N the size of the output buffer (it must be equal to the unpacked size
* of the item to be extracted).
* @param buffer the pre-allocated output buffer.
* @param index the index of the file to be extracted.
*/
template< std::size_t N >
void extractTo( byte_t (& buffer)[N], uint32_t index = 0 ) const { // NOLINT(*-avoid-c-arrays)
extractTo( buffer, N, index );
}
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( byte_t* buffer, std::size_t size, uint32_t index = 0 ) const {
extractTo( buffer, size, index );
}
/**
* @brief Extracts a file to the pre-allocated output buffer.
*
* @param buffer the pre-allocated output buffer.
* @param size the size of the output buffer (it must be equal to the unpacked size
* of the item to be extracted).
* @param index the index of the file to be extracted.
*/
void extractTo( byte_t* buffer, std::size_t size, uint32_t index = 0 ) const;
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( std::ostream& outStream, uint32_t index = 0 ) const {
extractTo( outStream, index );
}
/**
* @brief Extracts a file to the output stream.
*
* @param outStream the (binary) stream where the content of the archive will be put.
* @param index the index of the file to be extracted.
*/
void extractTo( std::ostream& outStream, uint32_t index = 0 ) const;
BIT7Z_DEPRECATED_MSG("Since v4.0; please, use the extractTo method.")
inline void extract( std::map< tstring, std::vector< byte_t > >& outMap ) const {
extractTo( outMap );
}
/**
* @brief Extracts the content of the archive to a map of memory buffers, where the keys are the paths
* of the files (inside the archive), and the values are their decompressed contents.
*
* @param outMap the output map.
*/
void extractTo( std::map< tstring, std::vector< byte_t > >& outMap ) const;
/**
* @brief Tests the archive without extracting its content.
*
* If the archive is not valid, a BitException is thrown!
*/
void test() const;
/**
* @brief Tests the item at the given index inside the archive without extracting it.
*
* If the archive is not valid, or there's no item at the given index, a BitException is thrown!
*
* @param index the index of the file to be tested.
*/
void testItem( uint32_t index ) const;
protected:
auto initUpdatableArchive( IOutArchive** newArc ) const -> HRESULT;
BIT7Z_NODISCARD auto close() const noexcept -> HRESULT;
friend class BitAbstractArchiveOpener;
friend class BitAbstractArchiveCreator;
friend class BitOutputArchive;
private:
IInArchive* mInArchive;
const BitInFormat* mDetectedFormat;
const BitAbstractArchiveHandler& mArchiveHandler;
tstring mArchivePath;
BIT7Z_NODISCARD
auto openArchiveStream( const fs::path& name, IInStream* inStream, ArchiveStartOffset startOffset ) -> IInArchive*;
public:
/**
* @brief An iterator for the elements contained in an archive.
*/
class ConstIterator {
public:
// iterator traits
using iterator_category BIT7Z_MAYBE_UNUSED = std::input_iterator_tag;
using value_type BIT7Z_MAYBE_UNUSED = BitArchiveItemOffset;
using reference = const BitArchiveItemOffset&;
using pointer = const BitArchiveItemOffset*;
using difference_type BIT7Z_MAYBE_UNUSED = uint32_t; //so that count_if returns an uint32_t
/**
* @brief Advances the iterator to the next element in the archive.
*
* @return the iterator pointing to the next element in the archive.
*/
auto operator++() noexcept -> ConstIterator&;
/**
* @brief Advances the iterator to the next element in the archive.
*
* @return the iterator before the advancement.
*/
auto operator++( int ) noexcept -> ConstIterator; // NOLINT(cert-dcl21-cpp)
/**
* @brief Compares the iterator with another iterator.
*
* @param other Another iterator.
*
* @return whether the two iterators point to the same element in the archive or not.
*/
auto operator==( const ConstIterator& other ) const noexcept -> bool;
/**
* @brief Compares the iterator with another iterator.
*
* @param other Another iterator.
*
* @return whether the two iterators point to the different elements in the archive or not.
*/
auto operator!=( const ConstIterator& other ) const noexcept -> bool;
/**
* @brief Accesses the pointed-to element in the archive.
*
* @return a reference to the pointed-to element in the archive.
*/
auto operator*() const noexcept -> reference;
/**
* @brief Accesses the pointed-to element in the archive.
*
* @return a pointer to the pointed-to element in the archive.
*/
auto operator->() const noexcept -> pointer;
private:
BitArchiveItemOffset mItemOffset;
ConstIterator( uint32_t itemIndex, const BitInputArchive& itemArchive ) noexcept;
friend class BitInputArchive;
};
BIT7Z_DEPRECATED_TYPEDEF( const_iterator, ConstIterator, "Use ConstIterator" );
/**
* @return an iterator to the first element of the archive; if the archive is empty,
* the returned iterator will be equal to the end() iterator.
*/
BIT7Z_NODISCARD auto begin() const noexcept -> BitInputArchive::ConstIterator;
/**
* @return an iterator to the element following the last element of the archive;
* this element acts as a placeholder: attempting to access it results in undefined behavior.
*/
BIT7Z_NODISCARD auto end() const noexcept -> BitInputArchive::ConstIterator;
/**
* @return an iterator to the first element of the archive; if the archive is empty,
* the returned iterator will be equal to the end() iterator.
*/
BIT7Z_NODISCARD auto cbegin() const noexcept -> BitInputArchive::ConstIterator;
/**
* @return an iterator to the element following the last element of the archive;
* this element acts as a placeholder: attempting to access it results in undefined behavior.
*/
BIT7Z_NODISCARD auto cend() const noexcept -> BitInputArchive::ConstIterator;
/**
* @brief Find an item in the archive that has the given path.
*
* @param path the path to be searched in the archive.
*
* @return an iterator to the item with the given path, or an iterator equal to the end() iterator
* if no item is found.
*/
BIT7Z_NODISCARD auto find( const tstring& path ) const noexcept -> BitInputArchive::ConstIterator;
/**
* @brief Find if there is an item in the archive that has the given path.
*
* @param path the path to be searched in the archive.
*
* @return true if and only if an item with the given path exists in the archive.
*/
BIT7Z_NODISCARD auto contains( const tstring& path ) const noexcept -> bool;
/**
* @brief Retrieve the item at the given index.
*
* @param index the index of the item to be retrieved.
*
* @return the item at the given index within the archive.
*/
BIT7Z_NODISCARD auto itemAt( uint32_t index ) const -> BitArchiveItemOffset;
};
} // namespace bit7z
#endif //BITINPUTARCHIVE_HPP

View file

@ -0,0 +1,172 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITITEMSVECTOR_HPP
#define BITITEMSVECTOR_HPP
#include <map>
#include <memory>
#include "bitabstractarchivehandler.hpp"
#include "bitfs.hpp"
#include "bittypes.hpp"
namespace bit7z {
using std::vector;
using std::map;
using std::unique_ptr;
namespace filesystem {
class FilesystemItem;
} // namespace filesystem
using filesystem::FilesystemItem;
struct GenericInputItem;
using GenericInputItemPtr = std::unique_ptr< GenericInputItem >;
using GenericInputItemVector = std::vector< GenericInputItemPtr >;
/** @cond **/
struct IndexingOptions {
bool recursive = true;
bool retainFolderStructure = false;
bool onlyFiles = false;
bool followSymlinks = true;
};
/** @endcond **/
/**
* @brief The BitItemsVector class represents a vector of generic input items, i.e., items that can come
* from the filesystem, from memory buffers, or from standard streams.
*/
class BitItemsVector final {
public:
using value_type = GenericInputItemPtr;
BitItemsVector() = default;
BitItemsVector( const BitItemsVector& ) = default;
BitItemsVector( BitItemsVector&& ) = default;
auto operator=( const BitItemsVector& ) -> BitItemsVector& = default;
auto operator=( BitItemsVector&& ) -> BitItemsVector& = default;
/**
* @brief Indexes the given directory, adding to the vector all the files that match the wildcard filter.
*
* @param inDir the directory to be indexed.
* @param filter (optional) the wildcard filter to be used for indexing;
* empty string means "index all files".
* @param policy (optional) the filtering policy to be applied to the matched items.
* @param options (optional) the settings to be used while indexing the given directory
* and all of its subdirectories.
*/
void indexDirectory( const fs::path& inDir,
const tstring& filter = {},
FilterPolicy policy = FilterPolicy::Include,
IndexingOptions options = {} );
/**
* @brief Indexes the given vector of filesystem paths, adding to the item vector all the files.
*
* @param inPaths the vector of filesystem paths.
* @param options (optional) the settings to be used while indexing the given directory
* and all of its subdirectories.
*/
void indexPaths( const std::vector< tstring >& inPaths, IndexingOptions options = {} );
/**
* @brief Indexes the given map of filesystem paths, adding to the vector all the files.
*
* @note Map keys represent the filesystem paths to be indexed; the corresponding mapped values are
* the user-defined (possibly different) paths wanted inside archives.
*
* @param inPaths map of filesystem paths with the corresponding user-defined path desired inside the
* output archive.
* @param options (optional) the settings to be used while indexing the given directory
* and all of its subdirectories.
*/
void indexPathsMap( const std::map< tstring, tstring >& inPaths, IndexingOptions options = {} );
/**
* @brief Indexes the given file path, with an optional user-defined path to be used in output archives.
*
* @note If a directory path is given, a BitException is thrown.
*
* @param inFile the path to the filesystem file to be indexed in the vector.
* @param name (optional) user-defined path to be used inside archives.
* @param followSymlinks (optional) whether to follow symbolic links or not.
*/
void indexFile( const tstring& inFile, const tstring& name = {}, bool followSymlinks = true );
/**
* @brief Indexes the given buffer, using the given name as a path when compressed in archives.
*
* @param inBuffer the buffer containing the file to be indexed in the vector.
* @param name user-defined path to be used inside archives.
*/
void indexBuffer( const std::vector< byte_t >& inBuffer, const tstring& name );
/**
* @brief Indexes the given standard input stream, using the given name as a path when compressed in archives.
*
* @param inStream the standard input stream of the file to be indexed in the vector.
* @param name user-defined path to be used inside archives.
*/
void indexStream( std::istream& inStream, const tstring& name );
/**
* @return the size of the items vector.
*/
BIT7Z_NODISCARD auto size() const -> std::size_t;
/**
* @param index the index of the desired item in the vector.
* @return a constant reference to the GenericInputItem at the given index.
*/
auto operator[]( GenericInputItemVector::size_type index ) const -> const GenericInputItem&;
/**
* @return an iterator to the first element of the vector; if the vector is empty,
* the returned iterator will be equal to the end() iterator.
*/
BIT7Z_NODISCARD auto begin() const noexcept -> GenericInputItemVector::const_iterator;
/**
* @return an iterator to the element following the last element of the vector;
* this element acts as a placeholder: attempting to access it results in undefined behavior.
*/
BIT7Z_NODISCARD auto end() const noexcept -> GenericInputItemVector::const_iterator;
/**
* @return an iterator to the first element of the vector; if the vector is empty,
* the returned iterator will be equal to the end() iterator.
*/
BIT7Z_NODISCARD auto cbegin() const noexcept -> GenericInputItemVector::const_iterator;
/**
* @return an iterator to the element following the last element of the vector;
* this element acts as a placeholder: attempting to access it results in undefined behavior.
*/
BIT7Z_NODISCARD auto cend() const noexcept -> GenericInputItemVector::const_iterator;
~BitItemsVector();
private:
GenericInputItemVector mItems;
void indexItem( const FilesystemItem& item, IndexingOptions options );
};
} // namespace bit7z
#endif //BITITEMSVECTOR_HPP

View file

@ -0,0 +1,27 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITMEMCOMPRESSOR_HPP
#define BITMEMCOMPRESSOR_HPP
#include "bitcompressor.hpp"
namespace bit7z {
/**
* @brief The BitMemCompressor alias allows compressing memory buffers.
* The compressed archives can be saved to the filesystem, standard streams, or memory buffers.
*
* It let decide various properties of the produced archive, such as the password
* protection and the compression level desired.
*/
using BitMemCompressor BIT7Z_MAYBE_UNUSED = BitCompressor< const std::vector< byte_t >& >;
} // namespace bit7z
#endif // BITMEMCOMPRESSOR_HPP

View file

@ -0,0 +1,24 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITMEMEXTRACTOR_HPP
#define BITMEMEXTRACTOR_HPP
#include "bitextractor.hpp"
namespace bit7z {
/**
* @brief The BitMemExtractor alias allows extracting the content of in-memory archives.
*/
using BitMemExtractor BIT7Z_MAYBE_UNUSED = BitExtractor< const std::vector< byte_t >& >;
} // namespace bit7z
#endif // BITMEMEXTRACTOR_HPP

View file

@ -0,0 +1,368 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITOUTPUTARCHIVE_HPP
#define BITOUTPUTARCHIVE_HPP
#include <istream>
#include <set>
#include "bitabstractarchivecreator.hpp"
#include "bititemsvector.hpp"
#include "bitexception.hpp" //for FailedFiles
#include "bitpropvariant.hpp"
//! @cond IGNORE_BLOCK_IN_DOXYGEN
struct ISequentialInStream;
template< typename T >
class CMyComPtr;
//! @endcond
namespace bit7z {
using std::istream;
using DeletedItems = std::set< uint32_t >;
/* General note: I tried my best to explain how indices work here, but it is a bit complex. */
/* We introduce a strong index type to differentiate between indices in the output
* archive (uint32_t, as used by the UpdateCallback), and the corresponding indexes
* in the input archive (InputIndex). In this way, we avoid implicit conversions
* between the two kinds of indices.
*
* UpdateCallback uses indices in the range [0, BitOutputArchive::itemsCount() - 1]
*
* Now, if the user doesn't delete any item in the input archive, itemsCount()
* is just equal to <n° of items in the input archive> + <n° of newly added items>.
* In this case, an InputIndex value is just equal to the index used by UpdateCallback.
*
* On the contrary, if the user wants to delete an item in the input archive, the value
* of an InputIndex may differ from the corresponding UpdateCallback's index.
*
* Note: given an InputIndex i:
* if i < mInputArchiveItemsCount, the item is old (old item in the input archive);
* if i >= mInputArchiveItemsCount, the item is new (added by the user); */
enum class InputIndex : std::uint32_t {};
class UpdateCallback;
/**
* @brief The BitOutputArchive class, given a creator object, allows creating new archives.
*/
class BitOutputArchive {
public:
/**
* @brief Constructs a BitOutputArchive object for a completely new archive.
*
* @param creator the reference to the BitAbstractArchiveCreator object containing all the settings to
* be used for creating the new archive.
*/
explicit BitOutputArchive( const BitAbstractArchiveCreator& creator );
/**
* @brief Constructs a BitOutputArchive object, opening an (optional) input file archive.
*
* If a non-empty input file path is passed, the corresponding archive will be opened and
* used as a base for the creation of the new archive. Otherwise, the class will behave
* as if it is creating a completely new archive.
*
* @param creator the reference to the BitAbstractArchiveCreator object containing all the settings to
* be used for creating the new archive and reading the (optional) input archive.
* @param inFile (optional) the path to an input archive file.
*/
explicit BitOutputArchive( const BitAbstractArchiveCreator& creator,
const tstring& inFile,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitOutputArchive object, opening an input file archive from the given buffer.
*
* If a non-empty input buffer is passed, the archive file it contains will be opened and
* used as a base for the creation of the new archive. Otherwise, the class will behave
* as if it is creating a completely new archive.
*
* @param creator the reference to the BitAbstractArchiveCreator object containing all the settings to
* be used for creating the new archive and reading the (optional) input archive.
* @param inBuffer the buffer containing an input archive file.
*/
BitOutputArchive( const BitAbstractArchiveCreator& creator,
const buffer_t& inBuffer,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
/**
* @brief Constructs a BitOutputArchive object, reading an input file archive from the given std::istream.
*
* @param creator the reference to the BitAbstractArchiveCreator object containing all the settings to
* be used for creating the new archive and reading the (optional) input archive.
* @param inStream the standard input stream of the input archive file.
*/
BitOutputArchive( const BitAbstractArchiveCreator& creator,
std::istream& inStream,
ArchiveStartOffset startOffset = ArchiveStartOffset::None );
BitOutputArchive( const BitOutputArchive& ) = delete;
BitOutputArchive( BitOutputArchive&& ) = delete;
auto operator=( const BitOutputArchive& ) -> BitOutputArchive& = delete;
auto operator=( BitOutputArchive&& ) -> BitOutputArchive& = delete;
/**
* @brief Adds all the items that can be found by indexing the given vector of filesystem paths.
*
* @param inPaths the vector of filesystem paths.
*/
void addItems( const std::vector< tstring >& inPaths );
/**
* @brief Adds all the items that can be found by indexing the keys of the given map of filesystem paths;
* the corresponding mapped values are the user-defined paths wanted inside the output archive.
*
* @param inPaths map of filesystem paths with the corresponding user-defined path desired inside the
* output archive.
*/
void addItems( const std::map< tstring, tstring >& inPaths );
/**
* @brief Adds the given file path, with an optional user-defined path to be used in the output archive.
*
* @note If a directory path is given, a BitException is thrown.
*
* @param inFile the path to the filesystem file to be added to the output archive.
* @param name (optional) user-defined path to be used inside the output archive.
*/
void addFile( const tstring& inFile, const tstring& name = {} );
/**
* @brief Adds the given buffer file, using the given name as a path when compressed in the output archive.
*
* @param inBuffer the buffer containing the file to be added to the output archive.
* @param name user-defined path to be used inside the output archive.
*/
void addFile( const std::vector< byte_t >& inBuffer, const tstring& name );
/**
* @brief Adds the given standard input stream, using the given name as a path when compressed
* in the output archive.
*
* @param inStream the input stream to be added.
* @param name the name of the file inside the output archive.
*/
void addFile( std::istream& inStream, const tstring& name );
/**
* @brief Adds all the files in the given vector of filesystem paths.
*
* @note Paths to directories are ignored.
*
* @param inFiles the vector of paths to files.
*/
void addFiles( const std::vector< tstring >& inFiles );
/**
* @brief Adds all the files inside the given directory path that match the given wildcard filter.
*
* @param inDir the directory where to search for files to be added to the output archive.
* @param filter the wildcard filter to be used for searching the files.
* @param recursive recursively search the files in the given directory and all of its subdirectories.
*/
void addFiles( const tstring& inDir, const tstring& filter, bool recursive );
/**
* @brief Adds all the files inside the given directory path that match the given wildcard filter.
*
* @param inDir the directory where to search for files to be added to the output archive.
* @param filter (optional) the wildcard filter to be used for searching the files.
* @param recursive (optional) recursively search the files in the given directory
* and all of its subdirectories.
* @param policy (optional) the filtering policy to be applied to the matched items.
*/
void addFiles( const tstring& inDir,
const tstring& filter = BIT7Z_STRING( "*" ),
FilterPolicy policy = FilterPolicy::Include,
bool recursive = true );
/**
* @brief Adds the given directory path and all its content.
*
* @param inDir the path of the directory to be added to the archive.
*/
void addDirectory( const tstring& inDir );
/**
* @brief Adds the contents of the given directory path.
*
* This function iterates through the specified directory and adds its contents
* based on the provided wildcard filter. Optionally, the operation can be
* recursive, meaning it will include subdirectories and their contents.
*
* @param inDir the directory where to search for files to be added to the output archive.
* @param filter the wildcard filter to be used for searching the files.
* @param recursive recursively search the files in the given directory and all of its subdirectories.
*/
void addDirectoryContents( const tstring& inDir, const tstring& filter, bool recursive );
/**
* @brief Adds the contents of the given directory path.
*
* This function iterates through the specified directory and adds its contents
* based on the provided wildcard filter and policy. Optionally, the operation can be
* recursive, meaning it will include subdirectories and their contents.
*
* @param inDir the directory where to search for files to be added to the output archive.
* @param filter (optional) the wildcard filter to be used for searching the files.
* @param recursive (optional) recursively search the files in the given directory
* and all of its subdirectories.
* @param policy (optional) the filtering policy to be applied to the matched items.
*/
void addDirectoryContents( const tstring& inDir,
const tstring& filter = BIT7Z_STRING( "*" ),
FilterPolicy policy = FilterPolicy::Include,
bool recursive = true );
/**
* @brief Compresses all the items added to this object to the specified archive file path.
*
* @note If this object was created by passing an input archive file path, and this latter is the same as
* the outFile path parameter, the file will be updated.
*
* @param outFile the output archive file path.
*/
void compressTo( const tstring& outFile );
/**
* @brief Compresses all the items added to this object to the specified buffer.
*
* @param outBuffer the output buffer.
*/
void compressTo( std::vector< byte_t >& outBuffer );
/**
* @brief Compresses all the items added to this object to the specified buffer.
*
* @param outStream the output standard stream.
*/
void compressTo( std::ostream& outStream );
/**
* @return the total number of items added to the output archive object.
*/
auto itemsCount() const -> uint32_t;
/**
* @return a constant reference to the BitAbstractArchiveHandler object containing the
* settings for writing the output archive.
*/
auto handler() const noexcept -> const BitAbstractArchiveHandler&;
/**
* @return a constant reference to the BitAbstractArchiveHandler object containing the
* settings for writing the output archive.
*/
auto creator() const noexcept -> const BitAbstractArchiveCreator&;
/**
* @brief Default destructor.
*/
virtual ~BitOutputArchive() = default;
protected:
virtual auto itemProperty( InputIndex index, BitProperty property ) const -> BitPropVariant;
virtual auto itemStream( InputIndex index, ISequentialInStream** inStream ) const -> HRESULT;
virtual auto hasNewData( uint32_t index ) const noexcept -> bool;
virtual auto hasNewProperties( uint32_t index ) const noexcept -> bool;
auto itemInputIndex( uint32_t newIndex ) const noexcept -> InputIndex;
auto outputItemProperty( uint32_t index, BitProperty property ) const -> BitPropVariant;
auto outputItemStream( uint32_t index, ISequentialInStream** inStream ) const -> HRESULT;
auto indexInArchive( uint32_t index ) const noexcept -> uint32_t;
inline auto inputArchive() const -> BitInputArchive* {
return mInputArchive.get();
}
inline void setInputArchive( std::unique_ptr< BitInputArchive >&& inputArchive ) {
mInputArchive = std::move( inputArchive );
}
inline auto inputArchiveItemsCount() const -> uint32_t {
return mInputArchiveItemsCount;
}
inline void setDeletedIndex( uint32_t index ) {
mDeletedItems.insert( index );
}
inline auto isDeletedIndex( uint32_t index ) const -> bool {
return mDeletedItems.find( index ) != mDeletedItems.cend();
}
inline auto hasDeletedIndexes() const -> bool {
return !mDeletedItems.empty();
}
inline auto hasNewItems() const -> bool {
return mNewItemsVector.size() > 0;
}
friend class UpdateCallback;
private:
const BitAbstractArchiveCreator& mArchiveCreator;
unique_ptr< BitInputArchive > mInputArchive;
uint32_t mInputArchiveItemsCount;
BitItemsVector mNewItemsVector;
DeletedItems mDeletedItems;
mutable FailedFiles mFailedFiles;
/* mInputIndices:
* - Position i = index in range [0, itemsCount() - 1] used by UpdateCallback.
* - Value at position i = corresponding index in the input archive (type InputIndex).
*
* If there are some deleted items, then i != mInputIndices[i]
* (at least for values of i greater than the index of the first deleted item).
*
* Otherwise, if there are no deleted items, the vector is empty, and itemInputIndex(i)
* will return InputIndex with value i.
*
* This vector is either empty, or it has size equal to itemsCount() (thanks to updateInputIndices()). */
std::vector< InputIndex > mInputIndices;
auto initOutArchive() const -> CMyComPtr< IOutArchive >;
auto initOutFileStream( const fs::path& outArchive, bool updatingArchive ) const -> CMyComPtr< IOutStream >;
BitOutputArchive( const BitAbstractArchiveCreator& creator,
const fs::path& inArc,
ArchiveStartOffset archiveStart );
void compressToFile( const fs::path& outFile, UpdateCallback* updateCallback );
void compressOut( IOutArchive* outArc, IOutStream* outStream, UpdateCallback* updateCallback );
void setArchiveProperties( IOutArchive* outArchive ) const;
void updateInputIndices();
};
} // namespace bit7z
#endif //BITOUTPUTARCHIVE_HPP

View file

@ -0,0 +1,461 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITPROPVARIANT_HPP
#define BITPROPVARIANT_HPP
#include <chrono>
#include <cstdint>
#include "bitdefines.hpp"
#include "bittypes.hpp"
#include "bitwindows.hpp"
namespace bit7z {
/**
* @brief A type representing a time point measured using the system clock.
*/
using time_type = std::chrono::time_point< std::chrono::system_clock >;
/**
* @brief The BitProperty enum represents the archive/item properties that 7-zip can read or write.
*/
enum struct BitProperty : PROPID {
NoProperty = 0, ///<
MainSubfile, ///<
HandlerItemIndex, ///<
Path, ///<
Name, ///<
Extension, ///<
IsDir, ///<
Size, ///<
PackSize, ///<
Attrib, ///<
CTime, ///<
ATime, ///<
MTime, ///<
Solid, ///<
Commented, ///<
Encrypted, ///<
SplitBefore, ///<
SplitAfter, ///<
DictionarySize, ///<
CRC, ///<
Type, ///<
IsAnti, ///<
Method, ///<
HostOS, ///<
FileSystem, ///<
User, ///<
Group, ///<
Block, ///<
Comment, ///<
Position, ///<
Prefix, ///<
NumSubDirs, ///<
NumSubFiles, ///<
UnpackVer, ///<
Volume, ///<
IsVolume, ///<
Offset, ///<
Links, ///<
NumBlocks, ///<
NumVolumes, ///<
TimeType, ///<
Bit64, ///<
BigEndian, ///<
Cpu, ///<
PhySize, ///<
HeadersSize, ///<
Checksum, ///<
Characts, ///<
Va, ///<
Id, ///<
ShortName, ///<
CreatorApp, ///<
SectorSize, ///<
PosixAttrib, ///<
SymLink, ///<
Error, ///<
TotalSize, ///<
FreeSpace, ///<
ClusterSize, ///<
VolumeName, ///<
LocalName, ///<
Provider, ///<
NtSecure, ///<
IsAltStream, ///<
IsAux, ///<
IsDeleted, ///<
IsTree, ///<
Sha1, ///<
Sha256, ///<
ErrorType, ///<
NumErrors, ///<
ErrorFlags, ///<
WarningFlags, ///<
Warning, ///<
NumStreams, ///<
NumAltStreams, ///<
AltStreamsSize, ///<
VirtualSize, ///<
UnpackSize, ///<
TotalPhySize, ///<
VolumeIndex, ///<
SubType, ///<
ShortComment, ///<
CodePage, ///<
IsNotArcType, ///<
PhySizeCantBeDetected, ///<
ZerosTailIsAllowed, ///<
TailSize, ///<
EmbeddedStubSize, ///<
NtReparse, ///<
HardLink, ///<
INode, ///<
StreamId, ///<
ReadOnly, ///<
OutName, ///<
CopyLink ///<
};
/**
* @brief The BitPropVariantType enum represents the possible types that a BitPropVariant can store.
*/
enum struct BitPropVariantType : uint32_t {
Empty, ///< Empty BitPropVariant type
Bool, ///< Boolean BitPropVariant type
String, ///< String BitPropVariant type
UInt8, ///< 8-bit unsigned int BitPropVariant type
UInt16, ///< 16-bit unsigned int BitPropVariant type
UInt32, ///< 32-bit unsigned int BitPropVariant type
UInt64, ///< 64-bit unsigned int BitPropVariant type
Int8, ///< 8-bit signed int BitPropVariant type
Int16, ///< 16-bit signed int BitPropVariant type
Int32, ///< 32-bit signed int BitPropVariant type
Int64, ///< 64-bit signed int BitPropVariant type
FileTime ///< FILETIME BitPropVariant type
};
/**
* @brief The BitPropVariant struct is a light extension to the WinAPI PROPVARIANT struct providing useful getters.
*/
struct BitPropVariant final : public PROPVARIANT {
/**
* @brief Constructs an empty BitPropVariant object.
*/
BitPropVariant();
/**
* @brief Copy constructs this BitPropVariant from another one.
*
* @param other the variant to be copied.
*/
BitPropVariant( const BitPropVariant& other );
/**
* @brief Move constructs this BitPropVariant from another one.
*
* @param other the variant to be moved.
*/
BitPropVariant( BitPropVariant&& other ) noexcept;
/**
* @brief Constructs a boolean BitPropVariant
*
* @param value the bool value of the BitPropVariant
*/
explicit BitPropVariant( bool value ) noexcept;
/**
* @brief Constructs a string BitPropVariant from a null-terminated C wide string
*
* @param value the null-terminated C wide string value of the BitPropVariant
*/
explicit BitPropVariant( const wchar_t* value );
/**
* @brief Constructs a string BitPropVariant from a wstring
*
* @param value the wstring value of the BitPropVariant
*/
explicit BitPropVariant( const std::wstring& value );
/**
* @brief Constructs an 8-bit unsigned integer BitPropVariant
*
* @param value the uint8_t value of the BitPropVariant
*/
explicit BitPropVariant( uint8_t value ) noexcept;
/**
* @brief Constructs a 16-bit unsigned integer BitPropVariant
*
* @param value the uint16_t value of the BitPropVariant
*/
explicit BitPropVariant( uint16_t value ) noexcept;
/**
* @brief Constructs a 32-bit unsigned integer BitPropVariant
*
* @param value the uint32_t value of the BitPropVariant
*/
explicit BitPropVariant( uint32_t value ) noexcept;
/**
* @brief Constructs a 64-bit unsigned integer BitPropVariant
*
* @param value the uint64_t value of the BitPropVariant
*/
explicit BitPropVariant( uint64_t value ) noexcept;
/**
* @brief Constructs an 8-bit integer BitPropVariant
*
* @param value the int8_t value of the BitPropVariant
*/
explicit BitPropVariant( int8_t value ) noexcept;
/**
* @brief Constructs a 16-bit integer BitPropVariant
*
* @param value the int16_t value of the BitPropVariant
*/
explicit BitPropVariant( int16_t value ) noexcept;
/**
* @brief Constructs a 32-bit integer BitPropVariant
*
* @param value the int32_t value of the BitPropVariant
*/
explicit BitPropVariant( int32_t value ) noexcept;
/**
* @brief Constructs a 64-bit integer BitPropVariant
*
* @param value the int64_t value of the BitPropVariant
*/
explicit BitPropVariant( int64_t value ) noexcept;
/**
* @brief Constructs a FILETIME BitPropVariant
*
* @param value the FILETIME value of the BitPropVariant
*/
explicit BitPropVariant( FILETIME value ) noexcept;
/**
* @brief BitPropVariant destructor.
*
* @note This is not virtual to maintain the same memory layout of the base struct!
*/
~BitPropVariant();
/**
* @brief Copy assignment operator.
*
* @param other the variant to be copied.
*
* @return a reference to *this object (with the copied values from other).
*/
auto operator=( const BitPropVariant& other ) -> BitPropVariant&;
/**
* @brief Move assignment operator.
*
* @param other the variant to be moved.
*
* @return a reference to *this object (with the moved values from other).
*/
auto operator=( BitPropVariant&& other ) noexcept -> BitPropVariant&;
/**
* @brief Assignment operator
*
* @note this will work only for T types for which a BitPropVariant constructor is defined!
*
* @param value the value to be assigned to the object
*
* @return a reference to *this object having the value as new variant value
*/
template< typename T >
auto operator=( const T& value ) noexcept( std::is_integral< T >::value ) -> BitPropVariant& {
*this = BitPropVariant{ value };
return *this;
}
/**
* @return the boolean value of this variant
* (it throws an exception if the variant is not a boolean value).
*/
BIT7Z_NODISCARD auto getBool() const -> bool;
/**
* @return the string value of this variant
* (it throws an exception if the variant is not a string).
*/
BIT7Z_NODISCARD auto getString() const -> tstring;
/**
* @return the native string value of this variant
* (it throws an exception if the variant is not a string).
*/
BIT7Z_NODISCARD auto getNativeString() const -> native_string;
/**
* @return the 8-bit unsigned integer value of this variant
* (it throws an exception if the variant is not an 8-bit unsigned integer).
*/
BIT7Z_NODISCARD auto getUInt8() const -> uint8_t;
/**
* @return the 16-bit unsigned integer value of this variant
* (it throws an exception if the variant is not an 8 or 16-bit unsigned integer).
*/
BIT7Z_NODISCARD auto getUInt16() const -> uint16_t;
/**
* @return the 32-bit unsigned integer value of this variant
* (it throws an exception if the variant is not an 8, 16 or 32-bit unsigned integer).
*/
BIT7Z_NODISCARD auto getUInt32() const -> uint32_t;
/**
* @return the 64-bit unsigned integer value of this variant
* (it throws an exception if the variant is not an 8, 16, 32 or 64-bit unsigned integer).
*/
BIT7Z_NODISCARD auto getUInt64() const -> uint64_t;
/**
* @return the 8-bit integer value of this variant
* (it throws an exception if the variant is not an 8-bit integer).
*/
BIT7Z_NODISCARD auto getInt8() const -> int8_t;
/**
* @return the 16-bit integer value of this variant
* (it throws an exception if the variant is not an 8 or 16-bit integer).
*/
BIT7Z_NODISCARD auto getInt16() const -> int16_t;
/**
* @return the 32-bit integer value of this variant
* (it throws an exception if the variant is not an 8, 16 or 32-bit integer).
*/
BIT7Z_NODISCARD auto getInt32() const -> int32_t;
/**
* @return the 64-bit integer value of this variant
* (it throws an exception if the variant is not an 8, 16, 32 or 64-bit integer).
*/
BIT7Z_NODISCARD auto getInt64() const -> int64_t;
/**
* @return the FILETIME value of this variant
* (it throws an exception if the variant is not a filetime).
*/
BIT7Z_NODISCARD auto getFileTime() const -> FILETIME;
/**
* @return the FILETIME value of this variant converted to std::time_point
* (it throws an exception if the variant is not a filetime).
*/
BIT7Z_NODISCARD auto getTimePoint() const -> time_type;
/**
* @return the value of this variant converted from any supported type to std::wstring.
*/
BIT7Z_NODISCARD auto toString() const -> tstring;
/**
* @return a boolean value indicating whether the variant is empty.
*/
BIT7Z_NODISCARD auto isEmpty() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is a boolean value.
*/
BIT7Z_NODISCARD auto isBool() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is a string.
*/
BIT7Z_NODISCARD auto isString() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8-bit unsigned integer.
*/
BIT7Z_NODISCARD auto isUInt8() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8 or 16-bit unsigned integer.
*/
BIT7Z_NODISCARD auto isUInt16() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8, 16 or 32-bit unsigned integer.
*/
BIT7Z_NODISCARD auto isUInt32() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8, 16, 32 or 64-bit unsigned integer.
*/
BIT7Z_NODISCARD auto isUInt64() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8-bit integer.
*/
BIT7Z_NODISCARD auto isInt8() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8 or 16-bit integer.
*/
BIT7Z_NODISCARD auto isInt16() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8, 16 or 32-bit integer.
*/
BIT7Z_NODISCARD auto isInt32() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is an 8, 16, 32 or 64-bit integer.
*/
BIT7Z_NODISCARD auto isInt64() const noexcept -> bool;
/**
* @return a boolean value indicating whether the variant is a FILETIME structure.
*/
BIT7Z_NODISCARD auto isFileTime() const noexcept -> bool;
/**
* @return the BitPropVariantType of this variant.
*/
BIT7Z_NODISCARD auto type() const -> BitPropVariantType;
/**
* @brief Clears the current value of the variant object
*/
void clear() noexcept;
private:
void internalClear() noexcept;
friend auto operator==( const BitPropVariant& lhs, const BitPropVariant& rhs ) noexcept -> bool;
friend auto operator!=( const BitPropVariant& lhs, const BitPropVariant& rhs ) noexcept -> bool;
};
auto operator==( const BitPropVariant& lhs, const BitPropVariant& rhs ) noexcept -> bool;
auto operator!=( const BitPropVariant& lhs, const BitPropVariant& rhs ) noexcept -> bool;
} // namespace bit7z
#endif // BITPROPVARIANT_HPP

View file

@ -0,0 +1,28 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITSTREAMCOMPRESSOR_HPP
#define BITSTREAMCOMPRESSOR_HPP
#include "bitcompressor.hpp"
namespace bit7z {
/**
* @brief The BitStreamCompressor alias allows compressing data from standard input streams.
* The compressed archives can be saved to the filesystem, standard streams, or memory buffers.
*
* It let decide various properties of the produced archive, such as the password
* protection and the compression level desired.
*/
using BitStreamCompressor BIT7Z_MAYBE_UNUSED = BitCompressor< std::istream& >;
} // namespace bit7z
#endif // BITSTREAMCOMPRESSOR_HPP

View file

@ -0,0 +1,24 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITSTREAMEXTRACTOR_HPP
#define BITSTREAMEXTRACTOR_HPP
#include "bitextractor.hpp"
namespace bit7z {
/**
* @brief The BitStreamExtractor alias allows extracting the content of in-memory archives.
*/
using BitStreamExtractor BIT7Z_MAYBE_UNUSED = BitExtractor< std::istream& >;
} // namespace bit7z
#endif // BITSTREAMEXTRACTOR_HPP

View file

@ -0,0 +1,130 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITTYPES_HPP
#define BITTYPES_HPP
#include <string>
#include <vector>
// Must be included here since the user might have manually enabled a BIT7Z_* compilation option
// by uncommenting the corresponding macro define in bitdefines.hpp.
#include "bitdefines.hpp"
#ifdef BIT7Z_REGEX_MATCHING
#include <regex>
#endif
namespace bit7z {
/**
* @brief A type representing a byte.
*/
#ifdef BIT7Z_USE_STD_BYTE
#if __cpp_lib_byte
using byte_t = std::byte;
#else
enum class byte_t : unsigned char {}; //same as std::byte_t
#endif
#else
using byte_t = unsigned char;
#endif
/** @cond */
using buffer_t = std::vector< byte_t >;
using index_t = std::ptrdiff_t; //like gsl::index (https://github.com/microsoft/GSL)
template< class Char >
struct StringTraits;
template<>
struct StringTraits< char > {
template< class T >
static inline auto convertToString( T value ) -> std::string {
return std::to_string( value );
}
};
template<>
struct StringTraits< wchar_t > {
template< class T >
static inline auto convertToString( T value ) -> std::wstring {
return std::to_wstring( value );
}
};
/** @endcond */
/**
* Native string type of the system.
* @note On Windows, it is an alias of `std::wstring`.
*/
#ifdef _WIN32
using native_string = std::wstring;
#define BIT7Z_NATIVE_STRING_( str ) L##str
#define BIT7Z_NATIVE_STRING( str ) BIT7Z_NATIVE_STRING_( str )
#else
using native_string = std::string;
#define BIT7Z_NATIVE_STRING( str ) str
#endif
using native_char = native_string::value_type;
/**
* @note On Windows, if the `BIT7Z_USE_NATIVE_STRING` option is enabled, `tchar` is an alias of `wchar_t`.
*/
#if defined( BIT7Z_USE_NATIVE_STRING ) && defined( _WIN32 ) // Windows with native strings
using tchar = wchar_t;
#define BIT7Z_STRING( str ) BIT7Z_NATIVE_STRING_( str )
#else // Unix, and Windows with non-native strings
using tchar = char;
#define BIT7Z_STRING( str ) str
#endif
/**
* @note On Windows, if the `BIT7Z_USE_NATIVE_STRING` option is enabled, `tstring` is an alias for std::wstring.
* Otherwise, it is an alias for std::string (default).
*/
using tstring = std::basic_string< tchar >;
#ifdef BIT7Z_REGEX_MATCHING
/**
* @note On Windows, if the `BIT7Z_USE_NATIVE_STRING` option is enabled, `tregex` is an alias for std::wregex.
* Otherwise, it is an alias for std::regex (default).
*/
using tregex = std::basic_regex< tchar >;
#endif
template< typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type >
inline auto to_tstring( T arg ) -> std::basic_string< tchar > {
return StringTraits< tchar >::convertToString( arg );
}
/**
* Converts a native string to a tstring.
*
* @note On Linux or on Windows when BIT7Z_USE_NATIVE_STRING is used,
* both native_string and tstring are aliases of the same string type;
* in this case, no conversion is performed, and a const reference to the original string is returned.
*
* @param str The native string to be converted.
*
* @return the converted tstring.
*/
#if defined( _WIN32 ) && !defined( BIT7Z_USE_NATIVE_STRING )
auto to_tstring( const native_string& str ) -> tstring;
#else
auto to_tstring( const native_string& str ) -> const tstring&;
#endif
template< typename From, typename To >
using is_explicitly_convertible = std::integral_constant< bool, std::is_constructible< To, From >::value &&
!std::is_convertible< From, To >::value >;
} // namespace bit7z
#endif // BITTYPES_HPP

View file

@ -0,0 +1,159 @@
/*
* bit7z - A C++ static library to interface with the 7-zip shared libraries.
* Copyright (c) 2014-2023 Riccardo Ostani - All Rights Reserved.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef BITWINDOWS_HPP
#define BITWINDOWS_HPP
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#include <propidl.h>
#else
/* We don't have the "Windows.h" header on Unix systems, so in theory, we could use the "MyWindows.h" of p7zip/7-zip.
* However, some of bit7z's public API headers need some Win32 API structs like PROPVARIANT and GUID.
* Hence, it would result in the leak of p7zip/7-zip headers, making bit7z's clients dependent on them.
* Also, (publicly) forward declaring them and then (internally) using the "MyWindows.h" is impossible:
* the two different declarations would conflict, making the compilation fail.
*
* To avoid all these issues, we define the required Win32 API structs, constants, and type aliases,
* with the same definitions in the MyWindows.h header.
* We will use only this header and avoid including "MyWindows.h" or similar headers (e.g., StdAfx.h). */
#include <cerrno>
#include <cstdint>
#include <cstddef>
// Avoiding accidentally including p7zip's MyWindows.h, so that its inclusion is not needed in client code!
#ifndef __MYWINDOWS_H
#define __MYWINDOWS_H // NOLINT
#endif
// Avoiding accidentally including 7-zip's MyWindows.h, so that its inclusion is not needed in client code!
#ifndef __MY_WINDOWS_H
#define __MY_WINDOWS_H // NOLINT
#endif
// Avoiding accidentally including 7-zip's MyWindows.h, so that its inclusion is not needed in client code!
#ifndef ZIP7_INC_MY_WINDOWS_H // 7-zip 23.01+
#define ZIP7_INC_MY_WINDOWS_H
#endif
using std::size_t;
#define WINAPI
namespace bit7z {
// Win32 type aliases
using FARPROC = void*;
using HMODULE = void*;
using HRESULT = int;
using OLECHAR = wchar_t;
using BSTR = OLECHAR*;
using VARIANT_BOOL = short;
using VARTYPE = unsigned short;
using WORD = unsigned short;
using DWORD = unsigned int;
using ULONG = unsigned int;
using PROPID = ULONG;
// Error codes constants can be useful for bit7z's clients on Unix (since they don't have the Windows.h header).
#ifndef S_OK // Silencing cppcheck warning on E_NOTIMPL, probably a bug of cppcheck.
// Win32 HRESULT error codes.
constexpr auto S_OK = static_cast< HRESULT >( 0x00000000L );
constexpr auto S_FALSE = static_cast< HRESULT >( 0x00000001L );
constexpr auto E_NOTIMPL = static_cast< HRESULT >( 0x80004001L );
constexpr auto E_NOINTERFACE = static_cast< HRESULT >( 0x80004002L );
constexpr auto E_ABORT = static_cast< HRESULT >( 0x80004004L );
constexpr auto E_FAIL = static_cast< HRESULT >( 0x80004005L );
constexpr auto STG_E_INVALIDFUNCTION = static_cast< HRESULT >( 0x80030001L );
constexpr auto E_OUTOFMEMORY = static_cast< HRESULT >( 0x8007000EL );
constexpr auto E_INVALIDARG = static_cast< HRESULT >( 0x80070057L );
#endif
#ifndef ERROR_ALREADY_EXISTS
// Win32 error codes (defined by both p7zip and 7-zip as equivalent to POSIX error codes).
constexpr auto ERROR_ALREADY_EXISTS = EEXIST;
constexpr auto ERROR_DISK_FULL = ENOSPC;
constexpr auto ERROR_FILE_EXISTS = EEXIST;
constexpr auto ERROR_FILE_NOT_FOUND = ENOENT;
constexpr auto ERROR_INVALID_PARAMETER = EINVAL;
constexpr auto ERROR_INVALID_FUNCTION = EINVAL;
constexpr auto ERROR_INVALID_HANDLE = EBADF;
constexpr auto ERROR_OPEN_FAILED = EIO;
constexpr auto ERROR_PATH_NOT_FOUND = ENOENT;
constexpr auto ERROR_SEEK = EIO;
constexpr auto ERROR_READ_FAULT = EIO;
constexpr auto ERROR_WRITE_FAULT = EIO;
// Win32 error codes (defined by p7zip with the same values as in Windows API).
constexpr auto ERROR_NO_MORE_FILES = 0x100018;
constexpr auto ERROR_DIRECTORY = 267;
#endif
#ifndef CP_UTF8
// Win32 codepages
constexpr auto CP_UTF8 = 65001u;
#endif
// Win32 structs.
struct FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
};
struct LARGE_INTEGER {
int64_t QuadPart;
};
struct ULARGE_INTEGER {
uint64_t QuadPart;
};
struct PROPVARIANT {
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union {
#if defined( __arm__ ) || defined( __aarch64__ )
signed char cVal;
#else
char cVal;
#endif
unsigned char bVal;
short iVal;
unsigned short uiVal;
int lVal;
unsigned int ulVal;
int intVal;
unsigned int uintVal;
LARGE_INTEGER hVal;
ULARGE_INTEGER uhVal;
VARIANT_BOOL boolVal;
int scode;
FILETIME filetime;
BSTR bstrVal;
};
};
} // namespace bit7z
#endif
#endif //BITWINDOWS_HPP

View file

@ -368,9 +368,9 @@ int DLCTexturePack::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicen
nullptr // Unsupported
);
#else
const char *pchFilename=wstringtofilename(grf.getPath());
std::string pchFilename=wstringtofilename(grf.getPath());
HANDLE fileHandle = CreateFile(
pchFilename, // file name
pchFilename.c_str(), // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
nullptr, // Unused
@ -420,9 +420,9 @@ int DLCTexturePack::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicen
nullptr // Unsupported
);
#else
const char *pchFilename=wstringtofilename(grf.getPath());
auto pchFilename=wstringtofilename(grf.getPath());
HANDLE fileHandle = CreateFile(
pchFilename, // file name
pchFilename.c_str(), // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
nullptr, // Unused

View file

@ -1,12 +1,41 @@
#include "stdafx.h"
#include "FileTexturePack.h"
#include "TexturePackRepository.h"
#include "..\Minecraft.World\StringHelpers.h"
FileTexturePack::FileTexturePack(DWORD id, File *file, TexturePack *fallback) : AbstractTexturePack(id, file, file->getName(), fallback)
{
// 4J Stu - These calls need to be in the most derived version of the class
loadZipFile(file);
if (!zipFile) {
return;
}
loadColourTable();
loadIcon();
loadName();
loadName(file);
loadDescription();
checkTexSize();
}
DLCPack* FileTexturePack::getDLCPack()
{
return NULL;
}
bool FileTexturePack::hasAudio() { // todo - add audio replacement support
return false;
}
bool FileTexturePack::hasData()
{
return !_iconData.empty() && zipFile != nullptr;
}
bool FileTexturePack::isLoadingData()
{
return false;
}
void FileTexturePack::unload(Textures *textures)
@ -24,8 +53,35 @@ void FileTexturePack::unload(Textures *textures)
#endif
}
InputStream *FileTexturePack::getResourceImplementation(const wstring &name) //throws IOException
{
wstring FileTexturePack::getAnimationString(const wstring& textureName, const wstring& path, bool allowFallback) {
// copy paste of base class method, except I return null and check for existence in getResource
// so it is fine to skip checking if the file exists and this allows a decent speedup
std::wstring result = L"";
InputStream* fileStream = getResource(L"\\" + path + textureName + L".txt", true);
if (fileStream) {
InputStreamReader isr(fileStream);
BufferedReader br(&isr);
wstring line = br.readLine();
while (!line.empty())
{
line = trimString(line);
if (line.length() > 0)
{
result.append(L",");
result.append(line);
}
line = br.readLine();
}
delete fileStream;
}
return result;
}
InputStream *FileTexturePack::getResourceImplementation(const wstring &name) {
#if 0
loadZipFile();
@ -36,6 +92,12 @@ InputStream *FileTexturePack::getResourceImplementation(const wstring &name) //t
return zipFile.getInputStream(entry);
#endif
app.DebugPrintf("ZIP: resource - %ls\n", name.c_str());
auto entry = zipFile->getEntry(&name);
if (entry) {
return zipFile->getInputStream(entry.get());
}
return nullptr;
}
@ -49,19 +111,89 @@ bool FileTexturePack::hasFile(const wstring &name)
} catch (Exception e) {
return false;
}
#endif
#if (defined _WIN64)
return zipFile->hasFile(&name);
#endif
return false;
}
void FileTexturePack::loadZipFile() //throws IOException
BufferedImage* FileTexturePack::getImageResource(const wstring& file, bool filenameHasExtension, bool bTitleUpdateTexture, const wstring& drive){
app.DebugPrintf("ZIP: image - %ls\n", file.c_str());
if (file == L"terrain.png" && terrainAtlas.get() != nullptr)
return terrainAtlas.release();
if (file == L"items.png" && itemAtlas.get() != nullptr)
return itemAtlas.release();
std::wstring f = file;
auto it = AbstractTexturePack::INDEXED_TO_JAVA_MAP.find(L"res/" + file);
if (it != INDEXED_TO_JAVA_MAP.end()) {
f = L"assets/minecraft/textures/" + it->second;
}
auto folderSep = file.find_last_of(L"/") + 1;
auto find = file.find(L"res/");
if (folderSep != file.npos && file.find(L"res/") == 0)
f = file.substr(folderSep, file.length() - folderSep);
//f = L"assets/minecraft/textures/" + f;
auto imageData = zipFile->extract(&f);
if (!imageData.empty()) {
auto image = new BufferedImage(imageData.data(), imageData.size());
return image;
}
app.DebugPrintf("ZIP: failed to find %ls fetching from default\n", file.c_str());
TexturePackRepository* repo = Minecraft::GetInstance()->skins;
return repo->getDefault()->getImageResource(file, filenameHasExtension, bTitleUpdateTexture);
}
void FileTexturePack::loadIcon() {
if (zipFile->hasFile("pack.png")) {
app.DebugPrintf("Found pack.png in zip file, loading as icon\n");
// auto zipFileEntry = zipFile->getEntry(&std::wstring(L"pack.png"));
_iconData = zipFile->extract(&std::wstring(L"pack.png"));
if (!_iconData.empty()) {
iconImage = new BufferedImage(_iconData.data(), _iconData.size());
m_iconData = _iconData.data();
m_iconSize = _iconData.size();
} else
app.DebugPrintf("Failed to load pack.png from zip file\n");
}
}
PBYTE FileTexturePack::getPackIcon(DWORD& dwImageBytes) {
if (_iconData.empty()) loadIcon();
if (!_iconData.empty()) {
dwImageBytes = m_iconSize;
return _iconData.data();
}
return NULL;
}
void FileTexturePack::loadName(File *file) {
std::wstring name = file->getName();
int pathSep = max(name.find_last_of('/'), name.find_last_of('\\')) + 1;
int extSep = name.find_last_of('.');
if (extSep < 0) {
extSep = name.length();
}
name = name.substr(pathSep, extSep - pathSep);
texname = name;
}
void FileTexturePack::loadZipFile(File* file) //throws IOException
{
#if 0
if (zipFile != null) {
if (file == NULL || file->getName() == L"") {
return;
}
zipFile = new ZipFile(file);
#endif
zipFile = std::make_unique<ZipFile>(file);
}
bool FileTexturePack::isTerrainUpdateCompatible()

View file

@ -1,5 +1,6 @@
#pragma once
#include "AbstractTexturePack.h"
#include "../Minecraft.World/ZipFile.h"
//class ZipFile;
class BufferedImage;
class File;
@ -9,23 +10,35 @@ using namespace std;
class FileTexturePack : public AbstractTexturePack
{
private:
//ZipFile *zipFile;
std::unique_ptr<ZipFile> zipFile;
std::vector<BYTE> _iconData;
DWORD id;
bool _hasAudio;
public:
FileTexturePack(DWORD id, File *file, TexturePack *fallback);
//@Override
void unload(Textures *textures);
DLCPack* getDLCPack();
bool hasAudio();
bool hasData();
void loadIcon();
PBYTE getPackIcon(DWORD& dwImageBytes);
void loadName(File *file);
bool isLoadingData();
wstring getAnimationString(const wstring& textureName, const wstring& path, bool allowFallback);
protected:
InputStream *getResourceImplementation(const wstring &name); //throws IOException
InputStream* getResourceImplementation(const wstring& name);
public:
//@Override
bool hasFile(const wstring &name);
BufferedImage* getImageResource(const wstring& File, bool filenameHasExtension = false, bool bTitleUpdateTexture = false, const wstring& drive = L"");
private:
void loadZipFile(); //throws IOException
void loadZipFile(File* file);
public:
bool isTerrainUpdateCompatible();

View file

@ -1,35 +1,119 @@
#include "stdafx.h"
#include "FolderTexturePack.h"
#include "TexturePackRepository.h"
#include "..\Minecraft.World\StringHelpers.h"
FolderTexturePack::FolderTexturePack(DWORD id, const wstring &name, File *folder, TexturePack *fallback) : AbstractTexturePack(id, folder, name, fallback)
{
// 4J Stu - These calls need to be in the most derived version of the class
cacheFiles(*folder, folder->getPath().length() + 1);
loadColourTable();
loadIcon();
loadName();
loadDescription();
checkTexSize();
bUILoaded = false;
}
InputStream *FolderTexturePack::getResourceImplementation(const wstring &name) //throws IOException
DLCPack* FolderTexturePack::getDLCPack()
{
#if 0
final File file = new File(this.file, name.substring(1));
if (!file.exists()) {
throw new FileNotFoundException(name);
return NULL;
}
void FolderTexturePack::loadName() {
texname = file->getName();
}
void FolderTexturePack::loadIcon()
{
if (hasFile(L"pack.png") && _iconData.empty())
{
app.DebugPrintf("Found pack.png in folder, loading as icon\n");
File iconFile(file->getPath() + L"\\pack.png");
FileInputStream is(iconFile);
_iconData.resize(iconFile.length());
byteArray arr(iconFile.length());
is.read(arr, 0, _iconData.size());
memcpy(_iconData.data(), arr.data, _iconData.size());
delete arr.data;
if (!_iconData.empty()) {
iconImage = new BufferedImage(_iconData.data(), _iconData.size());
m_iconData = _iconData.data();
m_iconSize = _iconData.size();
}
else
app.DebugPrintf("Failed to load pack.png from folder\n");
}
}
void FolderTexturePack::loadDescription()
{
desc1 = L"";
desc2 = L"";
}
bool FolderTexturePack::hasData()
{
return _cachedFiles.find(L"pack.mcmeta") != _cachedFiles.end();
}
bool FolderTexturePack::isLoadingData()
{
return false;
}
void FolderTexturePack::cacheFiles(File &dir, int folderLen)
{
int i = 0;
for (auto file : *dir.listFiles()) {
if (i++ < 2) continue; // skip `.` and `..`
if (file->isDirectory()) {
cacheFiles(*file, folderLen);
} else {
_cachedFiles[file->getPath().substr(folderLen)] = file->getPath().substr(folderLen);
_cachedFiles[file->getName()] = file->getPath().substr(folderLen);
}
}
}
wstring FolderTexturePack::getAnimationString(const wstring& textureName, const wstring& path, bool allowFallback) {
// copy paste of base class method, except I return null and check for existence in getResource
std::wstring result = L"";
InputStream* fileStream = getResource(L"\\" + path + textureName + L".txt", true);
if (fileStream) {
InputStreamReader isr(fileStream);
BufferedReader br(&isr);
wstring line = br.readLine();
while (!line.empty())
{
line = trimString(line);
if (line.length() > 0)
{
result.append(L",");
result.append(line);
}
line = br.readLine();
}
delete fileStream;
}
return new BufferedInputStream(new FileInputStream(file));
#endif
return result;
}
wstring wDrive = L"";
InputStream *FolderTexturePack::getResourceImplementation(const wstring &name) //throws IOException
{
// Make the content package point to to the UPDATE: drive is needed
#ifdef _XBOX
wDrive=L"GAME:\\DummyTexturePack\\res";
#else
wDrive = L"Common\\DummyTexturePack\\res";
#endif
InputStream *resource = InputStream::getResourceAsStream(wDrive + name);
std::wstring wDrive = this->file->getPath();
if (!hasFile(name))
return nullptr;
InputStream *resource = InputStream::getResourceAsStream(name);
//InputStream *stream = DefaultTexturePack::class->getResourceAsStream(name);
//if (stream == nullptr)
//{
@ -40,11 +124,46 @@ InputStream *FolderTexturePack::getResourceImplementation(const wstring &name) /
return resource;
}
BufferedImage* FolderTexturePack::getImageResource(const wstring& file, bool filenameHasExtension, bool bTitleUpdateTexture, const wstring& drive) {
app.DebugPrintf("FolderPack: image - %ls\n", file.c_str());
if (file == L"terrain.png" && terrainAtlas.get() != nullptr)
return terrainAtlas.release();
if (file == L"items.png" && itemAtlas.get() != nullptr)
return itemAtlas.release();
std::wstring f = file;
auto it = AbstractTexturePack::INDEXED_TO_JAVA_MAP.find(L"res/" + file);
if (it != INDEXED_TO_JAVA_MAP.end()) {
f = L"assets/minecraft/textures/" + it->second;
}
f = replaceAll(f, L"/", L"\\");
if (hasFile(f)) {
f = _cachedFiles[f];
File img(this->file->getPath() + L"\\" + f);
FileInputStream is(img);
byteArray arr(img.length());
is.read(arr, 0, img.length());
return new BufferedImage(arr.data, arr.length);
}
app.DebugPrintf("FolderPack: failed to find %ls fetching from default\n", f.c_str());
TexturePackRepository* repo = Minecraft::GetInstance()->skins;
return repo->getDefault()->getImageResource(file, filenameHasExtension, bTitleUpdateTexture);
}
bool FolderTexturePack::hasFile(const wstring &name)
{
File file = File( getPath() + name);
return file.exists() && file.isFile();
//return true;
std::wstring f = name;
if (f.find(L"/") != f.npos)
for (int i = 0; i < f.length(); i++)
f[i] == L'/' ? f[i] = L'\\' : 0; // putting zero there just works ig
return _cachedFiles.find(f) != _cachedFiles.end();
}
bool FolderTexturePack::isTerrainUpdateCompatible()

View file

@ -6,19 +6,30 @@ class FolderTexturePack : public AbstractTexturePack
{
private:
bool bUILoaded;
unordered_map<wstring, wstring> _cachedFiles;
vector<byte> _iconData;
void cacheFiles(File& dir, int folderLen);
public:
FolderTexturePack(DWORD id, const wstring &name, File *folder, TexturePack *fallback);
DLCPack* getDLCPack();
void loadIcon();
void loadDescription();
bool hasData();
bool isLoadingData();
wstring getAnimationString(const wstring& textureName, const wstring& path, bool allowFallback);
protected:
//@Override
InputStream *getResourceImplementation(const wstring &name); //throws IOException
void loadName();
public:
//@Override
bool hasFile(const wstring &name);
bool isTerrainUpdateCompatible();
BufferedImage* getImageResource(const wstring& File, bool filenameHasExtension = false, bool bTitleUpdateTexture = false, const wstring& drive = L"");
// 4J Added
virtual wstring getPath(bool bTitleUpdateTexture = false, const char *pchBDPatchFilename=nullptr);
virtual void loadUI();

View file

@ -3331,7 +3331,7 @@ void LevelRenderer::registerTextures(IconRegister *iconRegister)
for (int i = 0; i < 10; i++)
{
breakingTextures[i] = iconRegister->registerIcon(L"destroy_" + std::to_wstring(i) );
breakingTextures[i] = iconRegister->registerIcon(L"destroy_stage_" + std::to_wstring(i) );
}
}

File diff suppressed because it is too large Load diff

View file

@ -81,8 +81,8 @@ void Settings::saveProperties()
stream << "# MinecraftConsoles dedicated server properties\r\n";
for (unordered_map<wstring, wstring>::const_iterator it = properties.begin(); it != properties.end(); ++it)
{
string key = string(wstringtochararray(it->first));
string value = string(wstringtochararray(it->second));
string key = wstringtofilename(it->first);
string value = wstringtofilename(it->second);
stream << key << "=" << value << "\r\n";
}
}

View file

@ -52,7 +52,9 @@ public:
virtual unsigned char getDLCSubPackId() = 0;
virtual ColourTable *getColourTable() = 0;
virtual ArchiveFile *getArchiveFile() = 0;
// Needed otherwise game go boom during unsafe cast
virtual DLCPack* getDLCInfoParentPack() { return NULL; }
virtual void generateStitched(unordered_map<wstring, Icon*> texturesByName) {}
private:
bool m_bHasAudio;

View file

@ -216,6 +216,59 @@ void TexturePackRepository::updateList()
delete texturePacks;
texturePacks = currentPacks;
#endif
File texturePackDir;
if (minecraft->workingDirectory.getPath() == L"")
texturePackDir = File(L"resourcepacks");
else
texturePackDir = File(minecraft->workingDirectory, L"resourcepacks");
if (!texturePackDir.exists()) {
texturePackDir.mkdir();
return;
}
int c = 0;
for (File* file : *texturePackDir.listFiles()) {
if (c++ < 2) continue; // Skip `.` and `..`
try {
std::wstring name = file->getName();
std::wstring zipEnd = L".zip";
if (file->isFile() && (name.size() >= zipEnd.size() && name.substr(name.size() - zipEnd.size()) == zipEnd)) {
app.DebugPrintf("Found zip file texture pack!");
app.DebugPrintf("Finding unique id...");
DWORD id = 0;
for (int i = 0; i < INT_MAX; i++)
if (cacheById.find(i) == cacheById.end()) {
id = i;
break;
}
FileTexturePack* tp = new FileTexturePack(id, file, DEFAULT_TEXTURE_PACK);
if (tp->hasData()) {
texturePacks->push_back(tp);
cacheById[id] = tp;
}
}
else if (file->isDirectory()) {
app.DebugPrintf("Found folder texture pack! %s", name.c_str());
DWORD id = 0;
for (int i = 0; i < INT_MAX; i++)
if (cacheById.find(i) == cacheById.end()) {
id = i;
break;
}
FolderTexturePack* tp = new FolderTexturePack(id, file->getName(), file, DEFAULT_TEXTURE_PACK);
if (tp->hasData()) {
texturePacks->push_back(tp);
cacheById[id] = tp;
}
}
}
catch (exception e) {
app.DebugPrintf("Error loading texture pack '%ls'!", file->getName());
__debugbreak();
}
}
}
wstring TexturePackRepository::getIdOrNull(File file)

View file

@ -1400,7 +1400,7 @@ BufferedImage *Textures::readImage(TEXTURE_NAME texId, const wstring& name) // 4
}
else
{
const char *pchName=wstringtofilename(name);
std::string pchName=wstringtofilename(name);
#ifdef __PS3__
if(app.GetBootedFromDiscPatch() && app.IsFileInPatchList(pchName))
{
@ -1423,7 +1423,7 @@ BufferedImage *Textures::readImage(TEXTURE_NAME texId, const wstring& name) // 4
drive = skins->getDefault()->getPath(isTu);
}
const char *pchDrive=wstringtofilename(drive);
std::string pchDrive=wstringtofilename(drive);
if(IsOriginalImage(texId, name) || isTu)
{

Binary file not shown.

View file

@ -160,20 +160,11 @@ public:
void dispose() {}
};
class ZipEntry
{
};
class ZipEntry;
class InputStream;
class File;
class ZipFile
{
public:
ZipFile(File *file) {}
InputStream *getInputStream(ZipEntry *entry) { return nullptr; }
ZipEntry *getEntry(const wstring& name) {return nullptr;}
void close() {}
};
class ZipFile;
class ImageIO
{

View file

@ -46,11 +46,13 @@ target_link_libraries(Minecraft.Server PRIVATE
"${CMAKE_SOURCE_DIR}/Minecraft.Client/${PLATFORM_NAME}/4JLibs/libs/4J_Input_d.lib"
"${CMAKE_SOURCE_DIR}/Minecraft.Client/${PLATFORM_NAME}/4JLibs/libs/4J_Storage_d.lib"
"${CMAKE_SOURCE_DIR}/Minecraft.Client/${PLATFORM_NAME}/4JLibs/libs/4J_Render_PC_d.lib"
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/libs/bit7z/lib/x64/Debug/bit7z.lib"
>
$<$<NOT:$<CONFIG:Debug>>: # Release 4J libraries
"${CMAKE_SOURCE_DIR}/Minecraft.Client/${PLATFORM_NAME}/4JLibs/libs/4J_Input.lib"
"${CMAKE_SOURCE_DIR}/Minecraft.Client/${PLATFORM_NAME}/4JLibs/libs/4J_Storage.lib"
"${CMAKE_SOURCE_DIR}/Minecraft.Client/${PLATFORM_NAME}/4JLibs/libs/4J_Render_PC.lib"
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/libs/bit7z/lib/x64/Release/bit7z.lib"
>
)

View file

@ -14,7 +14,7 @@ const unsigned int AnvilTile::ANVIL_NAMES[ANVIL_NAMES_LENGTH] = { IDS_TILE_ANVIL
wstring AnvilTile::TEXTURE_DAMAGE_NAMES[ANVIL_NAMES_LENGTH] = {
L"anvil_top", L"anvil_top_damaged_1", L"anvil_top_damaged_2"
L"anvil_top", L"chipped_anvil_top", L"damaged_anvil_top"
};
AnvilTile::AnvilTile(int id) : HeavyTile(id, Material::heavyMetal, isSolidRender() )
@ -46,7 +46,7 @@ Icon *AnvilTile::getTexture(int face, int data)
void AnvilTile::registerIcons(IconRegister *iconRegister)
{
icon = iconRegister->registerIcon(L"anvil_base");
icon = iconRegister->registerIcon(L"anvil");
icons = new Icon*[ANVIL_NAMES_LENGTH];
for (int i = 0; i < ANVIL_NAMES_LENGTH; i++)

View file

@ -14,11 +14,11 @@ const int ArmorItem::healthPerSlot[] = {
};
const wstring ArmorItem::LEATHER_OVERLAYS[] = {
L"helmetCloth_overlay", L"chestplateCloth_overlay", L"leggingsCloth_overlay", L"bootsCloth_overlay"
L"leather_helmet_overlay", L"leather_chestplate_overlay", L"leather_leggings_overlay", L"leather_boots_overlay"
};
const wstring ArmorItem::TEXTURE_EMPTY_SLOTS[] = {
L"slot_empty_helmet", L"slot_empty_chestplate", L"slot_empty_leggings", L"slot_empty_boots"
L"empty_armor_slot_helmet", L"empty_armor_slot_chestplate", L"empty_armor_slot_leggings", L"empty_armor_slot_boots"
};

View file

@ -14,9 +14,9 @@ public:
private:
static const int healthPerSlot[];
static const wstring LEATHER_OVERLAYS[] ;
public:
static const wstring LEATHER_OVERLAYS[];
static const wstring TEXTURE_EMPTY_SLOTS[];
private:

View file

@ -18,6 +18,7 @@ target_include_directories(Minecraft.World
"${CMAKE_BINARY_DIR}/generated/"
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_SOURCE_DIR}/include/"
"${CMAKE_CURRENT_SOURCE_DIR}/Common/libs/bit7z/include"
PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/x64headers"
)

View file

@ -5,6 +5,7 @@
CarrotTile::CarrotTile(int id) : CropTile(id)
{
stages = 4;
}
Icon *CarrotTile::getTexture(int face, int data)
@ -33,10 +34,11 @@ int CarrotTile::getBasePlantId()
return Item::carrots_Id;
}
void CarrotTile::registerIcons(IconRegister *iconRegister)
{
for (int i = 0; i < 4; i++)
{
icons[i] = iconRegister->registerIcon(getIconName() + L"_stage_" + std::to_wstring(i));
}
}
// updated base crop to be consistent
//void CarrotTile::registerIcons(IconRegister *iconRegister)
//{
// for (int i = 0; i < 4; i++)
// {
// icons[i] = iconRegister->registerIcon(getIconName() + L"_stage_" + std::to_wstring(i));
// }
//}

View file

@ -15,7 +15,4 @@ public:
protected:
int getBaseSeedId();
int getBasePlantId();
public:
void registerIcons(IconRegister *iconRegister);
};

View file

@ -367,5 +367,5 @@ void ChestTile::registerIcons(IconRegister *iconRegister)
{
// Register wood as the chest's icon, because it's used by the particles
// when destroying the chest
icon = iconRegister->registerIcon(L"planks_oak");
icon = iconRegister->registerIcon(L"oak_planks");
}

View file

@ -6,7 +6,7 @@
#include "net.minecraft.h"
#include "CocoaTile.h"
const wstring CocoaTile::TEXTURE_AGES[] = { L"cocoa_0", L"cocoa_1", L"cocoa_2"};
const wstring CocoaTile::TEXTURE_AGES[] = { L"cocoa_stage0", L"cocoa_stage1", L"cocoa_stage2"};
CocoaTile::CocoaTile(int id) : DirectionalTile(id, Material::plant, isSolidRender() )
{

View file

@ -27,10 +27,17 @@ int ColoredTile::getItemAuxValueForTileData(int data)
return (~data & 0xf);
}
wstring ColoredTile::getColoredIconName(int id)
{
return (id != DyePowderItem::SILVER ? DyePowderItem::COLOR_TEXTURES[id] : L"light_gray") + L"_" + getIconName();
}
void ColoredTile::registerIcons(IconRegister *iconRegister)
{
for (int i = 0; i < ICON_COUNT; i++)
{
icons[i] = iconRegister->registerIcon(getIconName() + L"_" + DyePowderItem::COLOR_TEXTURES[getItemAuxValueForTileData(i)]);
int val = getItemAuxValueForTileData(i);
auto colorName = (val != DyePowderItem::SILVER ? DyePowderItem::COLOR_TEXTURES[val] : L"light_gray");
icons[i] = iconRegister->registerIcon(colorName + L"_" + getIconName());
}
}

View file

@ -17,5 +17,6 @@ public:
virtual int getSpawnResourcesAuxValue(int data);
static int getTileDataForItemAuxValue(int auxValue);
static int getItemAuxValueForTileData(int data);
wstring getColoredIconName(int id);
virtual void registerIcons(IconRegister *iconRegister);
};

View file

@ -105,11 +105,11 @@ Connection::Connection(Socket *socket, const wstring& id, PacketListener *packet
m_hWakeReadThread = new C4JThread::Event;
m_hWakeWriteThread = new C4JThread::Event;
const char *szId = wstringtofilename(id);
std::string szId = wstringtofilename(id);
char readThreadName[256];
char writeThreadName[256];
sprintf_s(readThreadName, sizeof(readThreadName), "%.240s read\n", szId);
sprintf_s(writeThreadName, sizeof(writeThreadName), "%.240s write\n", szId);
sprintf_s(readThreadName, sizeof(readThreadName), "%.240s read\n", szId.c_str());
sprintf_s(writeThreadName, sizeof(writeThreadName), "%.240s write\n", szId.c_str());
readThread = new C4JThread(runRead, static_cast<void *>(this), readThreadName, READ_STACK_SIZE);
writeThread = new C4JThread(runWrite, this, writeThreadName, WRITE_STACK_SIZE);

View file

@ -982,10 +982,10 @@ void ConsoleSaveFileOriginal::DebugFlushToFile(void *compressedData /*= nullptr*
wstring wtemp = targetFileDir.getPath() + wstring(fileName);
LPCWSTR lpFileName = wtemp.c_str();
#else
LPCSTR lpFileName = wstringtofilename( targetFileDir.getPath() + wstring(fileName) );
std::string lpFileName = wstringtofilename( targetFileDir.getPath() + wstring(fileName) );
#endif
#ifndef __PSVITA__
HANDLE hSaveFile = CreateFile( lpFileName, GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, nullptr);
HANDLE hSaveFile = CreateFile( lpFileName.c_str(), GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, nullptr);
#endif
if(compressedData != nullptr && compressedDataSize > 0)

View file

@ -10,6 +10,7 @@ CropTile::CropTile(int id) : Bush(id)
setTicking(true);
updateDefaultShape();
icons = nullptr;
stages = 8;
setDestroyTime(0.0f);
setSoundType(SOUND_GRASS);
@ -163,10 +164,10 @@ int CropTile::cloneTileId(Level *level, int x, int y, int z)
void CropTile::registerIcons(IconRegister *iconRegister)
{
icons = new Icon*[8];
icons = new Icon*[stages];
for (int i = 0; i < 8; i++)
for (int i = 0; i < stages; i++)
{
icons[i] = iconRegister->registerIcon(L"crops_" + std::to_wstring(i));
icons[i] = iconRegister->registerIcon(iconName + L"_stage" + std::to_wstring(i));
}
}

View file

@ -27,6 +27,7 @@ public:
virtual Icon *getTexture(int face, int data);
virtual int getRenderShape();
protected:
int stages;
virtual int getBaseSeedId();
virtual int getBasePlantId();

View file

@ -134,8 +134,8 @@ int DetectorRailTile::getAnalogOutputSignal(Level *level, int x, int y, int z, i
void DetectorRailTile::registerIcons(IconRegister *iconRegister)
{
icons = new Icon*[2];
icons[0] = iconRegister->registerIcon(L"detectorRail");
icons[1] = iconRegister->registerIcon(L"detectorRail_on");
icons[0] = iconRegister->registerIcon(getIconName());
icons[1] = iconRegister->registerIcon(getIconName() + L"_on");
}
Icon *DetectorRailTile::getTexture(int face, int data)

View file

@ -69,8 +69,8 @@ Icon *DoorTile::getTexture(LevelSource *level, int x, int y, int z, int face)
void DoorTile::registerIcons(IconRegister *iconRegister)
{
iconTop[TEXTURE_NORMAL] = iconRegister->registerIcon(getIconName() + L"_upper");
iconBottom[TEXTURE_NORMAL] = iconRegister->registerIcon(getIconName() + L"_lower");
iconTop[TEXTURE_NORMAL] = iconRegister->registerIcon(getIconName() + L"_top");
iconBottom[TEXTURE_NORMAL] = iconRegister->registerIcon(getIconName() + L"_bottom");
iconTop[TEXTURE_FLIPPED] = new FlippedIcon(iconTop[TEXTURE_NORMAL], true, false);
iconBottom[TEXTURE_FLIPPED] = new FlippedIcon(iconBottom[TEXTURE_NORMAL], true, false);
}

View file

@ -16,7 +16,7 @@ void DropperTile::registerIcons(IconRegister *iconRegister)
{
icon = iconRegister->registerIcon(L"furnace_side");
iconTop = iconRegister->registerIcon(L"furnace_top");
iconFront = iconRegister->registerIcon(getIconName() + L"_front_horizontal");
iconFront = iconRegister->registerIcon(getIconName() + L"_front");
iconFrontVertical = iconRegister->registerIcon(getIconName() + L"_front_vertical");
}

View file

@ -62,7 +62,7 @@ const unsigned int DyePowderItem::COLOR_USE_DESCS[] =
};
const wstring DyePowderItem::COLOR_TEXTURES[] =
{ L"black", L"red", L"green", L"brown", L"blue", L"purple", L"cyan", L"silver", L"gray", L"pink",
{ L"black", L"red", L"green", L"brown", L"blue", L"purple", L"cyan", L"light_gray", L"gray", L"pink",
L"lime", L"yellow", L"light_blue", L"magenta", L"orange", L"white"};
const int DyePowderItem::COLOR_RGB[] =
@ -343,6 +343,6 @@ void DyePowderItem::registerIcons(IconRegister *iconRegister)
for (int i = 0; i < DYE_POWDER_ITEM_TEXTURE_COUNT; i++)
{
icons[i] = iconRegister->registerIcon(getIconName() + L"_" + COLOR_TEXTURES[i]);
icons[i] = iconRegister->registerIcon(COLOR_TEXTURES[i] + L"_" + getIconName());
}
}

View file

@ -96,7 +96,7 @@ void EnchantmentTableTile::setPlacedBy(Level *level, int x, int y, int z, shared
void EnchantmentTableTile::registerIcons(IconRegister *iconRegister)
{
icon = iconRegister->registerIcon(TEXTURE_SIDE);
iconTop = iconRegister->registerIcon(TEXTURE_TOP);
iconBottom = iconRegister->registerIcon(TEXTURE_BOTTOM);
icon = iconRegister->registerIcon(getIconName() + L"_side");
iconTop = iconRegister->registerIcon(getIconName() + L"_top");
iconBottom = iconRegister->registerIcon(getIconName() + L"_bottom");
}

View file

@ -154,6 +154,6 @@ int FarmTile::cloneTileId(Level *level, int x, int y, int z)
void FarmTile::registerIcons(IconRegister *iconRegister)
{
iconWet = iconRegister->registerIcon(L"farmland_wet");
iconDry = iconRegister->registerIcon(L"farmland_dry");
iconWet = iconRegister->registerIcon(L"farmland_moist");
iconDry = iconRegister->registerIcon(L"farmland");
}

View file

@ -37,7 +37,7 @@ File::File( const wstring& pathname ) //: parent( nullptr )
m_abstractPathName = pathname;
#ifdef _WINDOWS64
string path = wstringtochararray(m_abstractPathName);
string path = wstringtofilename(m_abstractPathName);
string finalPath = StorageManager.GetMountedPath(path.c_str());
if(finalPath.size() == 0) finalPath = path;
m_abstractPathName = convStringToWstring(finalPath);
@ -100,7 +100,7 @@ bool File::_delete()
#ifdef _UNICODE
BOOL result = DeleteFile( getPath().c_str() );
#else
BOOL result = DeleteFile( wstringtofilename(getPath()) );
BOOL result = DeleteFile( wstringtofilename(getPath()).c_str() );
#endif
if( result == 0 )
{
@ -123,7 +123,7 @@ bool File::mkdir() const
return CreateDirectory( getPath().c_str(), nullptr) != 0;
#else
return CreateDirectory( wstringtofilename(getPath()), nullptr) != 0;
return CreateDirectory( wstringtofilename(getPath()).c_str(), nullptr) != 0;
#endif
}
@ -175,9 +175,10 @@ bool File::mkdirs() const
}
}
#else
if( GetFileAttributes( wstringtofilename(pathToHere) ) == -1 )
auto fileName = wstringtofilename(pathToHere);
if( GetFileAttributes( fileName.c_str() ) == -1 )
{
DWORD result = CreateDirectory( wstringtofilename(pathToHere), nullptr);
DWORD result = CreateDirectory( fileName.c_str(), nullptr);
if( result == 0 )
{
// Failed to create
@ -210,7 +211,7 @@ bool File::exists() const
return GetFileAttributes( getPath().c_str() ) != -1;
#else
return GetFileAttributes( wstringtofilename(getPath()) ) != -1;
return GetFileAttributes( wstringtofilename(getPath()).c_str() ) != -1;
#endif
}
@ -237,12 +238,12 @@ bool File::renameTo(File dest)
// called, therefore we were getting sourcePath and destPath having the same value. The solution here is to
// make a copy of the sourcePath by storing it in a std::string
std::string sourcePath = wstringtofilename(getPath());
const char *destPath = wstringtofilename(dest.getPath());
std::string destPath = wstringtofilename(dest.getPath());
#ifdef _DURANGO
__debugbreak(); // TODO
BOOL result = false;
#else
BOOL result = MoveFile(sourcePath.c_str(), destPath);
BOOL result = MoveFile(sourcePath.c_str(), destPath.c_str());
#endif
if( result == 0 )
@ -386,7 +387,7 @@ std::vector<File *> *File::listFiles() const
}
#else
char path[MAX_PATH] {};
snprintf( path, MAX_PATH, "%s\\*", wstringtofilename( getPath() ) );
snprintf( path, MAX_PATH, "%s\\*", wstringtofilename( getPath() ).c_str() );
HANDLE hFind = FindFirstFile( path, &wfd);
if(hFind != INVALID_HANDLE_VALUE)
{
@ -513,7 +514,7 @@ bool File::isDirectory() const
#ifdef _UNICODE
return exists() && ( GetFileAttributes( getPath().c_str() ) & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
#else
return exists() && ( GetFileAttributes( wstringtofilename(getPath()) ) & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
return exists() && ( GetFileAttributes( wstringtofilename(getPath()).c_str() ) & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
#endif
}
@ -596,7 +597,7 @@ int64_t File::length()
);
#else
BOOL result = GetFileAttributesEx(
wstringtofilename(getPath()), // file or directory name
wstringtofilename(getPath()).c_str(), // file or directory name
GetFileExInfoStandard, // attribute
&fileInfoBuffer // attribute information
);
@ -634,7 +635,7 @@ int64_t File::lastModified()
);
#else
BOOL result = GetFileAttributesEx(
wstringtofilename(getPath()), // file or directory name
wstringtofilename(getPath()).c_str(), // file or directory name
GetFileExInfoStandard, // attribute
&fileInfoBuffer // attribute information
);

View file

@ -18,7 +18,7 @@
//SecurityException - if a security manager exists and its checkRead method denies read access to the file.
FileInputStream::FileInputStream(const File &file)
{
const char *pchFilename=wstringtofilename(file.getPath());
std::string pchFilename=wstringtofilename(file.getPath());
#ifdef _UNICODE
m_fileHandle = CreateFile(
file.getPath().c_str(), // file name
@ -31,7 +31,7 @@ FileInputStream::FileInputStream(const File &file)
);
#else
m_fileHandle = CreateFile(
pchFilename, // file name
pchFilename.c_str(), // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
nullptr, // Unused

View file

@ -31,7 +31,7 @@ FileOutputStream::FileOutputStream(const File &file) : m_fileHandle( INVALID_HAN
);
#else
m_fileHandle = CreateFile(
wstringtofilename(file.getPath()) , // file name
wstringtofilename(file.getPath()).c_str(), // file name
GENERIC_WRITE, // access mode
0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but...
nullptr, // Unused

View file

@ -55,7 +55,7 @@ shared_ptr<ItemInstance> FishingRodItem::use(shared_ptr<ItemInstance> instance,
void FishingRodItem::registerIcons(IconRegister *iconRegister)
{
icon = iconRegister->registerIcon(getIconName() + L"_uncast");
icon = iconRegister->registerIcon(getIconName());
emptyIcon = iconRegister->registerIcon(getIconName() + L"_cast");
}

View file

@ -64,7 +64,7 @@ Icon *FurnaceTile::getTexture(int face, int data)
void FurnaceTile::registerIcons(IconRegister *iconRegister)
{
icon = iconRegister->registerIcon(L"furnace_side");
iconFront = iconRegister->registerIcon(lit ? L"furnace_front_lit" : L"furnace_front");
iconFront = iconRegister->registerIcon(lit ? L"furnace_front_on" : L"furnace_front");
iconTop = iconRegister->registerIcon(L"furnace_top");
}

View file

@ -37,10 +37,10 @@ Icon *GrassTile::getTexture(LevelSource *level, int x, int y, int z, int face)
void GrassTile::registerIcons(IconRegister *iconRegister)
{
icon = iconRegister->registerIcon(L"grass_side");
iconTop = iconRegister->registerIcon(L"grass_top");
iconSnowSide = iconRegister->registerIcon(L"snow_side");
iconSideOverlay = iconRegister->registerIcon(L"grass_side_overlay");
icon = iconRegister->registerIcon(L"grass_block_side");
iconTop = iconRegister->registerIcon(L"grass_block_top");
iconSnowSide = iconRegister->registerIcon(L"grass_block_snow");
iconSideOverlay = iconRegister->registerIcon(L"grass_block_side_overlay");
}
int GrassTile::getColor() const

View file

@ -2,9 +2,9 @@
#include "net.minecraft.world.h"
#include "HugeMushroomTile.h"
const wstring HugeMushroomTile::TEXTURE_STEM = L"skin_stem";
const wstring HugeMushroomTile::TEXTURE_STEM = L"stem";
const wstring HugeMushroomTile::TEXTURE_INSIDE = L"inside";
const wstring HugeMushroomTile::TEXTURE_TYPE[] = {L"skin_brown", L"skin_red"};
const wstring HugeMushroomTile::TEXTURE_TYPE[] = {L"brown", L"red"};
HugeMushroomTile::HugeMushroomTile(int id, Material *material, int type) : Tile(id, material)
{
@ -63,9 +63,9 @@ void HugeMushroomTile::registerIcons(IconRegister *iconRegister)
for (int i = 0; i < HUGE_MUSHROOM_TEXTURE_COUNT; i++)
{
icons[i] = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_TYPE[i]);
icons[i] = iconRegister->registerIcon(TEXTURE_TYPE[i] + L"_" + getIconName());
}
iconInside = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_INSIDE);
iconStem = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_STEM);
iconStem = iconRegister->registerIcon(L"mushroom_" + TEXTURE_STEM);
}

View file

@ -254,109 +254,109 @@ Item *Item::nameTag = nullptr;
void Item::staticCtor()
{
Item::sword_wood = ( new WeaponItem(12, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_wood) ->setIconName(L"swordWood")->setDescriptionId(IDS_ITEM_SWORD_WOOD)->setUseDescriptionId(IDS_DESC_SWORD);
Item::sword_stone = ( new WeaponItem(16, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_stone) ->setIconName(L"swordStone")->setDescriptionId(IDS_ITEM_SWORD_STONE)->setUseDescriptionId(IDS_DESC_SWORD);
Item::sword_iron = ( new WeaponItem(11, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_iron) ->setIconName(L"swordIron")->setDescriptionId(IDS_ITEM_SWORD_IRON)->setUseDescriptionId(IDS_DESC_SWORD);
Item::sword_diamond = ( new WeaponItem(20, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_diamond) ->setIconName(L"swordDiamond")->setDescriptionId(IDS_ITEM_SWORD_DIAMOND)->setUseDescriptionId(IDS_DESC_SWORD);
Item::sword_gold = ( new WeaponItem(27, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_gold) ->setIconName(L"swordGold")->setDescriptionId(IDS_ITEM_SWORD_GOLD)->setUseDescriptionId(IDS_DESC_SWORD);
Item::sword_wood = ( new WeaponItem(12, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_wood) ->setIconName(L"wooden_sword")->setDescriptionId(IDS_ITEM_SWORD_WOOD)->setUseDescriptionId(IDS_DESC_SWORD);
Item::sword_stone = ( new WeaponItem(16, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_stone) ->setIconName(L"stone_sword")->setDescriptionId(IDS_ITEM_SWORD_STONE)->setUseDescriptionId(IDS_DESC_SWORD);
Item::sword_iron = ( new WeaponItem(11, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_iron) ->setIconName(L"iron_sword")->setDescriptionId(IDS_ITEM_SWORD_IRON)->setUseDescriptionId(IDS_DESC_SWORD);
Item::sword_diamond = ( new WeaponItem(20, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_diamond) ->setIconName(L"diamond_sword")->setDescriptionId(IDS_ITEM_SWORD_DIAMOND)->setUseDescriptionId(IDS_DESC_SWORD);
Item::sword_gold = ( new WeaponItem(27, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_gold) ->setIconName(L"golden_sword")->setDescriptionId(IDS_ITEM_SWORD_GOLD)->setUseDescriptionId(IDS_DESC_SWORD);
Item::shovel_wood = ( new ShovelItem(13, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_wood) ->setIconName(L"shovelWood")->setDescriptionId(IDS_ITEM_SHOVEL_WOOD)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::shovel_stone = ( new ShovelItem(17, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_stone) ->setIconName(L"shovelStone")->setDescriptionId(IDS_ITEM_SHOVEL_STONE)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::shovel_iron = ( new ShovelItem(0, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_iron) ->setIconName(L"shovelIron")->setDescriptionId(IDS_ITEM_SHOVEL_IRON)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::shovel_diamond = ( new ShovelItem(21, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_diamond) ->setIconName(L"shovelDiamond")->setDescriptionId(IDS_ITEM_SHOVEL_DIAMOND)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::shovel_gold = ( new ShovelItem(28, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_gold) ->setIconName(L"shovelGold")->setDescriptionId(IDS_ITEM_SHOVEL_GOLD)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::shovel_wood = ( new ShovelItem(13, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_wood) ->setIconName(L"wooden_shovel")->setDescriptionId(IDS_ITEM_SHOVEL_WOOD)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::shovel_stone = ( new ShovelItem(17, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_stone) ->setIconName(L"stone_shovel")->setDescriptionId(IDS_ITEM_SHOVEL_STONE)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::shovel_iron = ( new ShovelItem(0, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_iron) ->setIconName(L"iron_shovel")->setDescriptionId(IDS_ITEM_SHOVEL_IRON)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::shovel_diamond = ( new ShovelItem(21, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_diamond) ->setIconName(L"diamond_shovel")->setDescriptionId(IDS_ITEM_SHOVEL_DIAMOND)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::shovel_gold = ( new ShovelItem(28, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_gold) ->setIconName(L"golden_shovel")->setDescriptionId(IDS_ITEM_SHOVEL_GOLD)->setUseDescriptionId(IDS_DESC_SHOVEL);
Item::pickAxe_wood = ( new PickaxeItem(14, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_wood) ->setIconName(L"pickaxeWood")->setDescriptionId(IDS_ITEM_PICKAXE_WOOD)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::pickAxe_stone = ( new PickaxeItem(18, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_stone) ->setIconName(L"pickaxeStone")->setDescriptionId(IDS_ITEM_PICKAXE_STONE)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::pickAxe_iron = ( new PickaxeItem(1, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_iron) ->setIconName(L"pickaxeIron")->setDescriptionId(IDS_ITEM_PICKAXE_IRON)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::pickAxe_diamond = ( new PickaxeItem(22, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_diamond) ->setIconName(L"pickaxeDiamond")->setDescriptionId(IDS_ITEM_PICKAXE_DIAMOND)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::pickAxe_gold = ( new PickaxeItem(29, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_gold) ->setIconName(L"pickaxeGold")->setDescriptionId(IDS_ITEM_PICKAXE_GOLD)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::pickAxe_wood = ( new PickaxeItem(14, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_wood) ->setIconName(L"wooden_pickaxe")->setDescriptionId(IDS_ITEM_PICKAXE_WOOD)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::pickAxe_stone = ( new PickaxeItem(18, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_stone) ->setIconName(L"stone_pickaxe")->setDescriptionId(IDS_ITEM_PICKAXE_STONE)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::pickAxe_iron = ( new PickaxeItem(1, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_iron) ->setIconName(L"iron_pickaxe")->setDescriptionId(IDS_ITEM_PICKAXE_IRON)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::pickAxe_diamond = ( new PickaxeItem(22, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_diamond) ->setIconName(L"diamond_pickaxe")->setDescriptionId(IDS_ITEM_PICKAXE_DIAMOND)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::pickAxe_gold = ( new PickaxeItem(29, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_gold) ->setIconName(L"golden_pickaxe")->setDescriptionId(IDS_ITEM_PICKAXE_GOLD)->setUseDescriptionId(IDS_DESC_PICKAXE);
Item::hatchet_wood = ( new HatchetItem(15, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_wood) ->setIconName(L"hatchetWood")->setDescriptionId(IDS_ITEM_HATCHET_WOOD)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hatchet_stone = ( new HatchetItem(19, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_stone) ->setIconName(L"hatchetStone")->setDescriptionId(IDS_ITEM_HATCHET_STONE)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hatchet_iron = ( new HatchetItem(2, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_iron) ->setIconName(L"hatchetIron")->setDescriptionId(IDS_ITEM_HATCHET_IRON)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hatchet_diamond = ( new HatchetItem(23, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_diamond) ->setIconName(L"hatchetDiamond")->setDescriptionId(IDS_ITEM_HATCHET_DIAMOND)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hatchet_gold = ( new HatchetItem(30, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_gold) ->setIconName(L"hatchetGold")->setDescriptionId(IDS_ITEM_HATCHET_GOLD)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hatchet_wood = ( new HatchetItem(15, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_wood) ->setIconName(L"wooden_axe")->setDescriptionId(IDS_ITEM_HATCHET_WOOD)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hatchet_stone = ( new HatchetItem(19, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_stone) ->setIconName(L"stone_axe")->setDescriptionId(IDS_ITEM_HATCHET_STONE)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hatchet_iron = ( new HatchetItem(2, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_iron) ->setIconName(L"iron_axe")->setDescriptionId(IDS_ITEM_HATCHET_IRON)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hatchet_diamond = ( new HatchetItem(23, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_diamond) ->setIconName(L"diamond_axe")->setDescriptionId(IDS_ITEM_HATCHET_DIAMOND)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hatchet_gold = ( new HatchetItem(30, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_gold) ->setIconName(L"golden_axe")->setDescriptionId(IDS_ITEM_HATCHET_GOLD)->setUseDescriptionId(IDS_DESC_HATCHET);
Item::hoe_wood = ( new HoeItem(34, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_wood) ->setIconName(L"hoeWood")->setDescriptionId(IDS_ITEM_HOE_WOOD)->setUseDescriptionId(IDS_DESC_HOE);
Item::hoe_stone = ( new HoeItem(35, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_stone) ->setIconName(L"hoeStone")->setDescriptionId(IDS_ITEM_HOE_STONE)->setUseDescriptionId(IDS_DESC_HOE);
Item::hoe_iron = ( new HoeItem(36, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_iron) ->setIconName(L"hoeIron")->setDescriptionId(IDS_ITEM_HOE_IRON)->setUseDescriptionId(IDS_DESC_HOE);
Item::hoe_diamond = ( new HoeItem(37, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_diamond) ->setIconName(L"hoeDiamond")->setDescriptionId(IDS_ITEM_HOE_DIAMOND)->setUseDescriptionId(IDS_DESC_HOE);
Item::hoe_gold = ( new HoeItem(38, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_gold) ->setIconName(L"hoeGold")->setDescriptionId(IDS_ITEM_HOE_GOLD)->setUseDescriptionId(IDS_DESC_HOE);
Item::hoe_wood = ( new HoeItem(34, _Tier::WOOD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_wood) ->setIconName(L"wooden_hoe")->setDescriptionId(IDS_ITEM_HOE_WOOD)->setUseDescriptionId(IDS_DESC_HOE);
Item::hoe_stone = ( new HoeItem(35, _Tier::STONE) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_stone) ->setIconName(L"stone_hoe")->setDescriptionId(IDS_ITEM_HOE_STONE)->setUseDescriptionId(IDS_DESC_HOE);
Item::hoe_iron = ( new HoeItem(36, _Tier::IRON) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_iron) ->setIconName(L"iron_hoe")->setDescriptionId(IDS_ITEM_HOE_IRON)->setUseDescriptionId(IDS_DESC_HOE);
Item::hoe_diamond = ( new HoeItem(37, _Tier::DIAMOND) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_diamond) ->setIconName(L"diamond_hoe")->setDescriptionId(IDS_ITEM_HOE_DIAMOND)->setUseDescriptionId(IDS_DESC_HOE);
Item::hoe_gold = ( new HoeItem(38, _Tier::GOLD) ) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_gold) ->setIconName(L"golden_hoe")->setDescriptionId(IDS_ITEM_HOE_GOLD)->setUseDescriptionId(IDS_DESC_HOE);
Item::door_wood = ( new DoorItem(68, Material::wood) ) ->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"doorWood")->setDescriptionId(IDS_ITEM_DOOR_WOOD)->setUseDescriptionId(IDS_DESC_DOOR_WOOD);
Item::door_iron = ( new DoorItem(74, Material::metal) ) ->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_iron)->setIconName(L"doorIron")->setDescriptionId(IDS_ITEM_DOOR_IRON)->setUseDescriptionId(IDS_DESC_DOOR_IRON);
Item::door_wood = ( new DoorItem(68, Material::wood) ) ->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood)->setIconName(L"oak_door")->setDescriptionId(IDS_ITEM_DOOR_WOOD)->setUseDescriptionId(IDS_DESC_DOOR_WOOD);
Item::door_iron = ( new DoorItem(74, Material::metal) ) ->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_iron)->setIconName(L"iron_door")->setDescriptionId(IDS_ITEM_DOOR_IRON)->setUseDescriptionId(IDS_DESC_DOOR_IRON);
Item::helmet_leather = static_cast<ArmorItem *>((new ArmorItem(42, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_cloth)->setIconName(L"helmetCloth")->setDescriptionId(IDS_ITEM_HELMET_CLOTH)->setUseDescriptionId(IDS_DESC_HELMET_LEATHER));
Item::helmet_iron = static_cast<ArmorItem *>((new ArmorItem(50, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_iron)->setIconName(L"helmetIron")->setDescriptionId(IDS_ITEM_HELMET_IRON)->setUseDescriptionId(IDS_DESC_HELMET_IRON));
Item::helmet_diamond = static_cast<ArmorItem *>((new ArmorItem(54, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_diamond)->setIconName(L"helmetDiamond")->setDescriptionId(IDS_ITEM_HELMET_DIAMOND)->setUseDescriptionId(IDS_DESC_HELMET_DIAMOND));
Item::helmet_gold = static_cast<ArmorItem *>((new ArmorItem(58, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_gold)->setIconName(L"helmetGold")->setDescriptionId(IDS_ITEM_HELMET_GOLD)->setUseDescriptionId(IDS_DESC_HELMET_GOLD));
Item::helmet_leather = static_cast<ArmorItem *>((new ArmorItem(42, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_cloth)->setIconName(L"leather_helmet")->setDescriptionId(IDS_ITEM_HELMET_CLOTH)->setUseDescriptionId(IDS_DESC_HELMET_LEATHER));
Item::helmet_iron = static_cast<ArmorItem *>((new ArmorItem(50, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_iron)->setIconName(L"iron_helmet")->setDescriptionId(IDS_ITEM_HELMET_IRON)->setUseDescriptionId(IDS_DESC_HELMET_IRON));
Item::helmet_diamond = static_cast<ArmorItem *>((new ArmorItem(54, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_diamond)->setIconName(L"diamond_helmet")->setDescriptionId(IDS_ITEM_HELMET_DIAMOND)->setUseDescriptionId(IDS_DESC_HELMET_DIAMOND));
Item::helmet_gold = static_cast<ArmorItem *>((new ArmorItem(58, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_gold)->setIconName(L"golden_helmet")->setDescriptionId(IDS_ITEM_HELMET_GOLD)->setUseDescriptionId(IDS_DESC_HELMET_GOLD));
Item::chestplate_leather = static_cast<ArmorItem *>((new ArmorItem(43, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_cloth)->setIconName(L"chestplateCloth")->setDescriptionId(IDS_ITEM_CHESTPLATE_CLOTH)->setUseDescriptionId(IDS_DESC_CHESTPLATE_LEATHER));
Item::chestplate_iron = static_cast<ArmorItem *>((new ArmorItem(51, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_iron)->setIconName(L"chestplateIron")->setDescriptionId(IDS_ITEM_CHESTPLATE_IRON)->setUseDescriptionId(IDS_DESC_CHESTPLATE_IRON));
Item::chestplate_diamond = static_cast<ArmorItem *>((new ArmorItem(55, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_diamond)->setIconName(L"chestplateDiamond")->setDescriptionId(IDS_ITEM_CHESTPLATE_DIAMOND)->setUseDescriptionId(IDS_DESC_CHESTPLATE_DIAMOND));
Item::chestplate_gold = static_cast<ArmorItem *>((new ArmorItem(59, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_gold)->setIconName(L"chestplateGold")->setDescriptionId(IDS_ITEM_CHESTPLATE_GOLD)->setUseDescriptionId(IDS_DESC_CHESTPLATE_GOLD));
Item::chestplate_leather = static_cast<ArmorItem *>((new ArmorItem(43, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_cloth)->setIconName(L"leather_chestplate")->setDescriptionId(IDS_ITEM_CHESTPLATE_CLOTH)->setUseDescriptionId(IDS_DESC_CHESTPLATE_LEATHER));
Item::chestplate_iron = static_cast<ArmorItem *>((new ArmorItem(51, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_iron)->setIconName(L"iron_chestplate")->setDescriptionId(IDS_ITEM_CHESTPLATE_IRON)->setUseDescriptionId(IDS_DESC_CHESTPLATE_IRON));
Item::chestplate_diamond = static_cast<ArmorItem *>((new ArmorItem(55, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_diamond)->setIconName(L"diamond_chestplate")->setDescriptionId(IDS_ITEM_CHESTPLATE_DIAMOND)->setUseDescriptionId(IDS_DESC_CHESTPLATE_DIAMOND));
Item::chestplate_gold = static_cast<ArmorItem *>((new ArmorItem(59, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_gold)->setIconName(L"golden_chestplate")->setDescriptionId(IDS_ITEM_CHESTPLATE_GOLD)->setUseDescriptionId(IDS_DESC_CHESTPLATE_GOLD));
Item::leggings_leather = static_cast<ArmorItem *>((new ArmorItem(44, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_cloth)->setIconName(L"leggingsCloth")->setDescriptionId(IDS_ITEM_LEGGINGS_CLOTH)->setUseDescriptionId(IDS_DESC_LEGGINGS_LEATHER));
Item::leggings_iron = static_cast<ArmorItem *>((new ArmorItem(52, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_iron)->setIconName(L"leggingsIron")->setDescriptionId(IDS_ITEM_LEGGINGS_IRON)->setUseDescriptionId(IDS_DESC_LEGGINGS_IRON));
Item::leggings_diamond = static_cast<ArmorItem *>((new ArmorItem(56, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_diamond)->setIconName(L"leggingsDiamond")->setDescriptionId(IDS_ITEM_LEGGINGS_DIAMOND)->setUseDescriptionId(IDS_DESC_LEGGINGS_DIAMOND));
Item::leggings_gold = static_cast<ArmorItem *>((new ArmorItem(60, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_gold)->setIconName(L"leggingsGold")->setDescriptionId(IDS_ITEM_LEGGINGS_GOLD)->setUseDescriptionId(IDS_DESC_LEGGINGS_GOLD));
Item::leggings_leather = static_cast<ArmorItem *>((new ArmorItem(44, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_cloth)->setIconName(L"leather_leggings")->setDescriptionId(IDS_ITEM_LEGGINGS_CLOTH)->setUseDescriptionId(IDS_DESC_LEGGINGS_LEATHER));
Item::leggings_iron = static_cast<ArmorItem *>((new ArmorItem(52, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_iron)->setIconName(L"iron_leggings")->setDescriptionId(IDS_ITEM_LEGGINGS_IRON)->setUseDescriptionId(IDS_DESC_LEGGINGS_IRON));
Item::leggings_diamond = static_cast<ArmorItem *>((new ArmorItem(56, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_diamond)->setIconName(L"diamond_leggings")->setDescriptionId(IDS_ITEM_LEGGINGS_DIAMOND)->setUseDescriptionId(IDS_DESC_LEGGINGS_DIAMOND));
Item::leggings_gold = static_cast<ArmorItem *>((new ArmorItem(60, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_gold)->setIconName(L"golden_leggings")->setDescriptionId(IDS_ITEM_LEGGINGS_GOLD)->setUseDescriptionId(IDS_DESC_LEGGINGS_GOLD));
Item::helmet_chain = static_cast<ArmorItem *>((new ArmorItem(46, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_chain)->setIconName(L"helmetChain")->setDescriptionId(IDS_ITEM_HELMET_CHAIN)->setUseDescriptionId(IDS_DESC_HELMET_CHAIN));
Item::chestplate_chain = static_cast<ArmorItem *>((new ArmorItem(47, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_chain)->setIconName(L"chestplateChain")->setDescriptionId(IDS_ITEM_CHESTPLATE_CHAIN)->setUseDescriptionId(IDS_DESC_CHESTPLATE_CHAIN));
Item::leggings_chain = static_cast<ArmorItem *>((new ArmorItem(48, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_chain)->setIconName(L"leggingsChain")->setDescriptionId(IDS_ITEM_LEGGINGS_CHAIN)->setUseDescriptionId(IDS_DESC_LEGGINGS_CHAIN));
Item::boots_chain = static_cast<ArmorItem *>((new ArmorItem(49, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_chain)->setIconName(L"bootsChain")->setDescriptionId(IDS_ITEM_BOOTS_CHAIN)->setUseDescriptionId(IDS_DESC_BOOTS_CHAIN));
Item::helmet_chain = static_cast<ArmorItem *>((new ArmorItem(46, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_HEAD))->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_chain)->setIconName(L"chainmail_helmet")->setDescriptionId(IDS_ITEM_HELMET_CHAIN)->setUseDescriptionId(IDS_DESC_HELMET_CHAIN));
Item::chestplate_chain = static_cast<ArmorItem *>((new ArmorItem(47, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_TORSO))->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_chain)->setIconName(L"chainmail_chestplate")->setDescriptionId(IDS_ITEM_CHESTPLATE_CHAIN)->setUseDescriptionId(IDS_DESC_CHESTPLATE_CHAIN));
Item::leggings_chain = static_cast<ArmorItem *>((new ArmorItem(48, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_LEGS))->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_chain)->setIconName(L"chainmail_leggings")->setDescriptionId(IDS_ITEM_LEGGINGS_CHAIN)->setUseDescriptionId(IDS_DESC_LEGGINGS_CHAIN));
Item::boots_chain = static_cast<ArmorItem *>((new ArmorItem(49, ArmorItem::ArmorMaterial::CHAIN, 1, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_chain)->setIconName(L"chainmail_boots")->setDescriptionId(IDS_ITEM_BOOTS_CHAIN)->setUseDescriptionId(IDS_DESC_BOOTS_CHAIN));
Item::boots_leather = static_cast<ArmorItem *>((new ArmorItem(45, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_cloth)->setIconName(L"bootsCloth")->setDescriptionId(IDS_ITEM_BOOTS_CLOTH)->setUseDescriptionId(IDS_DESC_BOOTS_LEATHER));
Item::boots_iron = static_cast<ArmorItem *>((new ArmorItem(53, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_iron)->setIconName(L"bootsIron")->setDescriptionId(IDS_ITEM_BOOTS_IRON)->setUseDescriptionId(IDS_DESC_BOOTS_IRON));
Item::boots_diamond = static_cast<ArmorItem *>((new ArmorItem(57, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_diamond)->setIconName(L"bootsDiamond")->setDescriptionId(IDS_ITEM_BOOTS_DIAMOND)->setUseDescriptionId(IDS_DESC_BOOTS_DIAMOND));
Item::boots_gold = static_cast<ArmorItem *>((new ArmorItem(61, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_gold)->setIconName(L"bootsGold")->setDescriptionId(IDS_ITEM_BOOTS_GOLD)->setUseDescriptionId(IDS_DESC_BOOTS_GOLD));
Item::boots_leather = static_cast<ArmorItem *>((new ArmorItem(45, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_cloth)->setIconName(L"leather_boots")->setDescriptionId(IDS_ITEM_BOOTS_CLOTH)->setUseDescriptionId(IDS_DESC_BOOTS_LEATHER));
Item::boots_iron = static_cast<ArmorItem *>((new ArmorItem(53, ArmorItem::ArmorMaterial::IRON, 2, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_iron)->setIconName(L"iron_boots")->setDescriptionId(IDS_ITEM_BOOTS_IRON)->setUseDescriptionId(IDS_DESC_BOOTS_IRON));
Item::boots_diamond = static_cast<ArmorItem *>((new ArmorItem(57, ArmorItem::ArmorMaterial::DIAMOND, 3, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_diamond)->setIconName(L"diamond_boots")->setDescriptionId(IDS_ITEM_BOOTS_DIAMOND)->setUseDescriptionId(IDS_DESC_BOOTS_DIAMOND));
Item::boots_gold = static_cast<ArmorItem *>((new ArmorItem(61, ArmorItem::ArmorMaterial::GOLD, 4, ArmorItem::SLOT_FEET))->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_gold)->setIconName(L"golden_boots")->setDescriptionId(IDS_ITEM_BOOTS_GOLD)->setUseDescriptionId(IDS_DESC_BOOTS_GOLD));
Item::ironIngot = ( new Item(9) )->setIconName(L"ingotIron") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_iron)->setDescriptionId(IDS_ITEM_INGOT_IRON)->setUseDescriptionId(IDS_DESC_INGOT);
Item::goldIngot = ( new Item(10) )->setIconName(L"ingotGold") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold)->setDescriptionId(IDS_ITEM_INGOT_GOLD)->setUseDescriptionId(IDS_DESC_INGOT);
Item::ironIngot = ( new Item(9) )->setIconName(L"iron_ingot") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_iron)->setDescriptionId(IDS_ITEM_INGOT_IRON)->setUseDescriptionId(IDS_DESC_INGOT);
Item::goldIngot = ( new Item(10) )->setIconName(L"gold_ingot") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold)->setDescriptionId(IDS_ITEM_INGOT_GOLD)->setUseDescriptionId(IDS_DESC_INGOT);
// 4J-PB - todo - add materials and base types to the ones below
Item::bucket_empty = ( new BucketItem(69, 0) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_water)->setIconName(L"bucket")->setDescriptionId(IDS_ITEM_BUCKET)->setUseDescriptionId(IDS_DESC_BUCKET)->setMaxStackSize(16);
Item::bowl = ( new Item(25) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_wood)->setIconName(L"bowl")->setDescriptionId(IDS_ITEM_BOWL)->setUseDescriptionId(IDS_DESC_BOWL)->setMaxStackSize(64);
Item::bucket_water = ( new BucketItem(70, Tile::water_Id) ) ->setIconName(L"bucketWater")->setDescriptionId(IDS_ITEM_BUCKET_WATER)->setCraftingRemainingItem(Item::bucket_empty)->setUseDescriptionId(IDS_DESC_BUCKET_WATER);
Item::bucket_lava = ( new BucketItem(71, Tile::lava_Id) ) ->setIconName(L"bucketLava")->setDescriptionId(IDS_ITEM_BUCKET_LAVA)->setCraftingRemainingItem(Item::bucket_empty)->setUseDescriptionId(IDS_DESC_BUCKET_LAVA);
Item::bucket_milk = ( new MilkBucketItem(79) )->setIconName(L"milk")->setDescriptionId(IDS_ITEM_BUCKET_MILK)->setCraftingRemainingItem(Item::bucket_empty)->setUseDescriptionId(IDS_DESC_BUCKET_MILK);
Item::bucket_water = ( new BucketItem(70, Tile::water_Id) ) ->setIconName(L"water_bucket")->setDescriptionId(IDS_ITEM_BUCKET_WATER)->setCraftingRemainingItem(Item::bucket_empty)->setUseDescriptionId(IDS_DESC_BUCKET_WATER);
Item::bucket_lava = ( new BucketItem(71, Tile::lava_Id) ) ->setIconName(L"lava_bucket")->setDescriptionId(IDS_ITEM_BUCKET_LAVA)->setCraftingRemainingItem(Item::bucket_empty)->setUseDescriptionId(IDS_DESC_BUCKET_LAVA);
Item::bucket_milk = ( new MilkBucketItem(79) )->setIconName(L"milk_bucket")->setDescriptionId(IDS_ITEM_BUCKET_MILK)->setCraftingRemainingItem(Item::bucket_empty)->setUseDescriptionId(IDS_DESC_BUCKET_MILK);
Item::bow = static_cast<BowItem *>((new BowItem(5))->setIconName(L"bow")->setBaseItemTypeAndMaterial(eBaseItemType_bow, eMaterial_bow)->setDescriptionId(IDS_ITEM_BOW)->setUseDescriptionId(IDS_DESC_BOW));
Item::arrow = ( new Item(6) ) ->setIconName(L"arrow")->setBaseItemTypeAndMaterial(eBaseItemType_bow, eMaterial_arrow) ->setDescriptionId(IDS_ITEM_ARROW)->setUseDescriptionId(IDS_DESC_ARROW);
Item::compass = ( new CompassItem(89) ) ->setIconName(L"compass")->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_compass) ->setDescriptionId(IDS_ITEM_COMPASS)->setUseDescriptionId(IDS_DESC_COMPASS);
Item::clock = ( new ClockItem(91) ) ->setIconName(L"clock")->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_clock) ->setDescriptionId(IDS_ITEM_CLOCK)->setUseDescriptionId(IDS_DESC_CLOCK);
Item::map = static_cast<MapItem *>((new MapItem(102))->setIconName(L"map")->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_map)->setDescriptionId(IDS_ITEM_MAP)->setUseDescriptionId(IDS_DESC_MAP));
Item::map = static_cast<MapItem *>((new MapItem(102))->setIconName(L"filled_map")->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_map)->setDescriptionId(IDS_ITEM_MAP)->setUseDescriptionId(IDS_DESC_MAP));
Item::flintAndSteel = ( new FlintAndSteelItem(3) ) ->setIconName(L"flintAndSteel")->setBaseItemTypeAndMaterial(eBaseItemType_devicetool, eMaterial_flintandsteel)->setDescriptionId(IDS_ITEM_FLINT_AND_STEEL)->setUseDescriptionId(IDS_DESC_FLINTANDSTEEL);
Item::flintAndSteel = ( new FlintAndSteelItem(3) ) ->setIconName(L"flint_and_steel")->setBaseItemTypeAndMaterial(eBaseItemType_devicetool, eMaterial_flintandsteel)->setDescriptionId(IDS_ITEM_FLINT_AND_STEEL)->setUseDescriptionId(IDS_DESC_FLINTANDSTEEL);
Item::apple = ( new FoodItem(4, 4, FoodConstants::FOOD_SATURATION_LOW, false) ) ->setIconName(L"apple")->setDescriptionId(IDS_ITEM_APPLE)->setUseDescriptionId(IDS_DESC_APPLE);
Item::coal = ( new CoalItem(7) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_coal)->setIconName(L"coal")->setDescriptionId(IDS_ITEM_COAL)->setUseDescriptionId(IDS_DESC_COAL);
Item::diamond = ( new Item(8) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_diamond)->setIconName(L"diamond")->setDescriptionId(IDS_ITEM_DIAMOND)->setUseDescriptionId(IDS_DESC_DIAMONDS);
Item::stick = ( new Item(24) ) ->setIconName(L"stick")->handEquipped()->setDescriptionId(IDS_ITEM_STICK)->setUseDescriptionId(IDS_DESC_STICK);
Item::mushroomStew = ( new BowlFoodItem(26, 6) ) ->setIconName(L"mushroomStew")->setDescriptionId(IDS_ITEM_MUSHROOM_STEW)->setUseDescriptionId(IDS_DESC_MUSHROOMSTEW);
Item::mushroomStew = ( new BowlFoodItem(26, 6) ) ->setIconName(L"mushroom_stew")->setDescriptionId(IDS_ITEM_MUSHROOM_STEW)->setUseDescriptionId(IDS_DESC_MUSHROOMSTEW);
Item::string = ( new TilePlanterItem(31, Tile::tripWire) ) ->setIconName(L"string")->setDescriptionId(IDS_ITEM_STRING)->setUseDescriptionId(IDS_DESC_STRING);
Item::feather = ( new Item(32) ) ->setIconName(L"feather")->setDescriptionId(IDS_ITEM_FEATHER)->setUseDescriptionId(IDS_DESC_FEATHER);
Item::gunpowder = ( new Item(33) ) ->setIconName(L"sulphur")->setDescriptionId(IDS_ITEM_SULPHUR)->setUseDescriptionId(IDS_DESC_SULPHUR)->setPotionBrewingFormula(PotionBrewing::MOD_GUNPOWDER);
Item::gunpowder = ( new Item(33) ) ->setIconName(L"gunpowder")->setDescriptionId(IDS_ITEM_SULPHUR)->setUseDescriptionId(IDS_DESC_SULPHUR)->setPotionBrewingFormula(PotionBrewing::MOD_GUNPOWDER);
Item::seeds_wheat = ( new SeedItem(39, Tile::wheat_Id, Tile::farmland_Id) ) ->setIconName(L"seeds")->setDescriptionId(IDS_ITEM_WHEAT_SEEDS)->setUseDescriptionId(IDS_DESC_WHEAT_SEEDS);
Item::seeds_wheat = ( new SeedItem(39, Tile::wheat_Id, Tile::farmland_Id) ) ->setIconName(L"wheat_seeds")->setDescriptionId(IDS_ITEM_WHEAT_SEEDS)->setUseDescriptionId(IDS_DESC_WHEAT_SEEDS);
Item::wheat = ( new Item(40) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_wheat)->setIconName(L"wheat")->setDescriptionId(IDS_ITEM_WHEAT)->setUseDescriptionId(IDS_DESC_WHEAT);
Item::bread = ( new FoodItem(41, 5, FoodConstants::FOOD_SATURATION_NORMAL, false) ) ->setIconName(L"bread")->setDescriptionId(IDS_ITEM_BREAD)->setUseDescriptionId(IDS_DESC_BREAD);
Item::flint = ( new Item(62) ) ->setIconName(L"flint")->setDescriptionId(IDS_ITEM_FLINT)->setUseDescriptionId(IDS_DESC_FLINT);
Item::porkChop_raw = ( new FoodItem(63, 3, FoodConstants::FOOD_SATURATION_LOW, true) ) ->setIconName(L"porkchopRaw")->setDescriptionId(IDS_ITEM_PORKCHOP_RAW)->setUseDescriptionId(IDS_DESC_PORKCHOP_RAW);
Item::porkChop_cooked = ( new FoodItem(64, 8, FoodConstants::FOOD_SATURATION_GOOD, true) ) ->setIconName(L"porkchopCooked")->setDescriptionId(IDS_ITEM_PORKCHOP_COOKED)->setUseDescriptionId(IDS_DESC_PORKCHOP_COOKED);
Item::porkChop_raw = ( new FoodItem(63, 3, FoodConstants::FOOD_SATURATION_LOW, true) ) ->setIconName(L"porkchop")->setDescriptionId(IDS_ITEM_PORKCHOP_RAW)->setUseDescriptionId(IDS_DESC_PORKCHOP_RAW);
Item::porkChop_cooked = ( new FoodItem(64, 8, FoodConstants::FOOD_SATURATION_GOOD, true) ) ->setIconName(L"cooked_porkchop")->setDescriptionId(IDS_ITEM_PORKCHOP_COOKED)->setUseDescriptionId(IDS_DESC_PORKCHOP_COOKED);
Item::painting = ( new HangingEntityItem(65,eTYPE_PAINTING) ) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_cloth)->setIconName(L"painting")->setDescriptionId(IDS_ITEM_PAINTING)->setUseDescriptionId(IDS_DESC_PICTURE);
Item::apple_gold = ( new GoldenAppleItem(66, 4, FoodConstants::FOOD_SATURATION_SUPERNATURAL, false) )->setCanAlwaysEat()->setEatEffect(MobEffect::regeneration->id, 5, 1, 1.0f)
->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit,eMaterial_apple)->setIconName(L"appleGold")->setDescriptionId(IDS_ITEM_APPLE_GOLD);//->setUseDescriptionId(IDS_DESC_GOLDENAPPLE);
->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit,eMaterial_apple)->setIconName(L"golden_apple")->setDescriptionId(IDS_ITEM_APPLE_GOLD);//->setUseDescriptionId(IDS_DESC_GOLDENAPPLE);
Item::sign = ( new SignItem(67) ) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_wood)->setIconName(L"sign")->setDescriptionId(IDS_ITEM_SIGN)->setUseDescriptionId(IDS_DESC_SIGN);
Item::sign = ( new SignItem(67) ) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_wood)->setIconName(L"oak_sign")->setDescriptionId(IDS_ITEM_SIGN)->setUseDescriptionId(IDS_DESC_SIGN);
@ -365,24 +365,24 @@ void Item::staticCtor()
Item::redStone = ( new RedStoneItem(75) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_redstone)->setIconName(L"redstone")->setDescriptionId(IDS_ITEM_REDSTONE)->setUseDescriptionId(IDS_DESC_REDSTONE_DUST)->setPotionBrewingFormula(PotionBrewing::MOD_REDSTONE);
Item::snowBall = ( new SnowballItem(76) ) ->setIconName(L"snowball")->setDescriptionId(IDS_ITEM_SNOWBALL)->setUseDescriptionId(IDS_DESC_SNOWBALL);
Item::boat = ( new BoatItem(77) ) ->setIconName(L"boat")->setDescriptionId(IDS_ITEM_BOAT)->setUseDescriptionId(IDS_DESC_BOAT);
Item::boat = ( new BoatItem(77) ) ->setIconName(L"oak_boat")->setDescriptionId(IDS_ITEM_BOAT)->setUseDescriptionId(IDS_DESC_BOAT);
Item::leather = ( new Item(78) ) ->setIconName(L"leather")->setDescriptionId(IDS_ITEM_LEATHER)->setUseDescriptionId(IDS_DESC_LEATHER);
Item::brick = ( new Item(80) ) ->setIconName(L"brick")->setDescriptionId(IDS_ITEM_BRICK)->setUseDescriptionId(IDS_DESC_BRICK);
Item::clay = ( new Item(81) ) ->setIconName(L"clay")->setDescriptionId(IDS_ITEM_CLAY)->setUseDescriptionId(IDS_DESC_CLAY);
Item::reeds = ( new TilePlanterItem(82, Tile::reeds) ) ->setIconName(L"reeds")->setDescriptionId(IDS_ITEM_REEDS)->setUseDescriptionId(IDS_DESC_REEDS);
Item::clay = ( new Item(81) ) ->setIconName(L"clay_ball")->setDescriptionId(IDS_ITEM_CLAY)->setUseDescriptionId(IDS_DESC_CLAY);
Item::reeds = ( new TilePlanterItem(82, Tile::reeds) ) ->setIconName(L"sugar_cane")->setDescriptionId(IDS_ITEM_REEDS)->setUseDescriptionId(IDS_DESC_REEDS);
Item::paper = ( new Item(83) ) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_paper)->setIconName(L"paper")->setDescriptionId(IDS_ITEM_PAPER)->setUseDescriptionId(IDS_DESC_PAPER);
Item::book = ( new BookItem(84) ) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_book)->setIconName(L"book")->setDescriptionId(IDS_ITEM_BOOK)->setUseDescriptionId(IDS_DESC_BOOK);
Item::slimeBall = ( new Item(85) ) ->setIconName(L"slimeball")->setDescriptionId(IDS_ITEM_SLIMEBALL)->setUseDescriptionId(IDS_DESC_SLIMEBALL);
Item::minecart_chest = ( new MinecartItem(86, Minecart::TYPE_CHEST) ) ->setIconName(L"minecart_chest")->setDescriptionId(IDS_ITEM_MINECART_CHEST)->setUseDescriptionId(IDS_DESC_MINECARTWITHCHEST);
Item::minecart_furnace = ( new MinecartItem(87, Minecart::TYPE_FURNACE) )->setIconName(L"minecart_furnace")->setDescriptionId(IDS_ITEM_MINECART_FURNACE)->setUseDescriptionId(IDS_DESC_MINECARTWITHFURNACE);
Item::slimeBall = ( new Item(85) ) ->setIconName(L"slime_ball")->setDescriptionId(IDS_ITEM_SLIMEBALL)->setUseDescriptionId(IDS_DESC_SLIMEBALL);
Item::minecart_chest = ( new MinecartItem(86, Minecart::TYPE_CHEST) ) ->setIconName(L"chest_minecart")->setDescriptionId(IDS_ITEM_MINECART_CHEST)->setUseDescriptionId(IDS_DESC_MINECARTWITHCHEST);
Item::minecart_furnace = ( new MinecartItem(87, Minecart::TYPE_FURNACE) )->setIconName(L"furnace_minecart")->setDescriptionId(IDS_ITEM_MINECART_FURNACE)->setUseDescriptionId(IDS_DESC_MINECARTWITHFURNACE);
Item::egg = ( new EggItem(88) ) ->setIconName(L"egg")->setDescriptionId(IDS_ITEM_EGG)->setUseDescriptionId(IDS_DESC_EGG);
Item::fishingRod = static_cast<FishingRodItem *>((new FishingRodItem(90))->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_wood)->setIconName(L"fishingRod")->setDescriptionId(IDS_ITEM_FISHING_ROD)->setUseDescriptionId(IDS_DESC_FISHINGROD));
Item::yellowDust = ( new Item(92) ) ->setIconName(L"yellowDust")->setDescriptionId(IDS_ITEM_YELLOW_DUST)->setUseDescriptionId(IDS_DESC_YELLOW_DUST)->setPotionBrewingFormula(PotionBrewing::MOD_GLOWSTONE);
Item::fish_raw = ( new FoodItem(93, 2, FoodConstants::FOOD_SATURATION_LOW, false) ) ->setIconName(L"fishRaw")->setDescriptionId(IDS_ITEM_FISH_RAW)->setUseDescriptionId(IDS_DESC_FISH_RAW);
Item::fish_cooked = ( new FoodItem(94, 5, FoodConstants::FOOD_SATURATION_NORMAL, false) ) ->setIconName(L"fishCooked")->setDescriptionId(IDS_ITEM_FISH_COOKED)->setUseDescriptionId(IDS_DESC_FISH_COOKED);
Item::fishingRod = static_cast<FishingRodItem *>((new FishingRodItem(90))->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_wood)->setIconName(L"fishing_rod")->setDescriptionId(IDS_ITEM_FISHING_ROD)->setUseDescriptionId(IDS_DESC_FISHINGROD));
Item::yellowDust = ( new Item(92) ) ->setIconName(L"glowstone_dust")->setDescriptionId(IDS_ITEM_YELLOW_DUST)->setUseDescriptionId(IDS_DESC_YELLOW_DUST)->setPotionBrewingFormula(PotionBrewing::MOD_GLOWSTONE);
Item::fish_raw = ( new FoodItem(93, 2, FoodConstants::FOOD_SATURATION_LOW, false) ) ->setIconName(L"fish")->setDescriptionId(IDS_ITEM_FISH_RAW)->setUseDescriptionId(IDS_DESC_FISH_RAW);
Item::fish_cooked = ( new FoodItem(94, 5, FoodConstants::FOOD_SATURATION_NORMAL, false) ) ->setIconName(L"cooked_fish")->setDescriptionId(IDS_ITEM_FISH_COOKED)->setUseDescriptionId(IDS_DESC_FISH_COOKED);
Item::dye_powder = ( new DyePowderItem(95) ) ->setBaseItemTypeAndMaterial(eBaseItemType_dyepowder, eMaterial_dye)->setIconName(L"dyePowder")->setDescriptionId(IDS_ITEM_DYE_POWDER)->setUseDescriptionId(-1);
Item::dye_powder = ( new DyePowderItem(95) ) ->setBaseItemTypeAndMaterial(eBaseItemType_dyepowder, eMaterial_dye)->setIconName(L"dye")->setDescriptionId(IDS_ITEM_DYE_POWDER)->setUseDescriptionId(-1);
Item::bone = ( new Item(96) ) ->setIconName(L"bone")->setDescriptionId(IDS_ITEM_BONE)->handEquipped()->setUseDescriptionId(IDS_DESC_BONE);
Item::sugar = ( new Item(97) ) ->setIconName(L"sugar")->setDescriptionId(IDS_ITEM_SUGAR)->setUseDescriptionId(IDS_DESC_SUGAR)->setPotionBrewingFormula(PotionBrewing::MOD_SUGAR);
@ -392,69 +392,69 @@ void Item::staticCtor()
Item::bed = ( new BedItem(99) ) ->setMaxStackSize(1)->setIconName(L"bed")->setDescriptionId(IDS_ITEM_BED)->setUseDescriptionId(IDS_DESC_BED);
Item::repeater = ( new TilePlanterItem(100, static_cast<Tile *>(Tile::diode_off)) ) ->setIconName(L"diode")->setDescriptionId(IDS_ITEM_DIODE)->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER);
Item::repeater = ( new TilePlanterItem(100, static_cast<Tile *>(Tile::diode_off)) ) ->setIconName(L"repeater")->setDescriptionId(IDS_ITEM_DIODE)->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER);
Item::cookie = ( new FoodItem(101, 2, FoodConstants::FOOD_SATURATION_POOR, false) ) ->setIconName(L"cookie")->setDescriptionId(IDS_ITEM_COOKIE)->setUseDescriptionId(IDS_DESC_COOKIE);
Item::shears = static_cast<ShearsItem *>((new ShearsItem(103))->setIconName(L"shears")->setBaseItemTypeAndMaterial(eBaseItemType_devicetool, eMaterial_shears)->setDescriptionId(IDS_ITEM_SHEARS)->setUseDescriptionId(IDS_DESC_SHEARS));
Item::melon = (new FoodItem(104, 2, FoodConstants::FOOD_SATURATION_LOW, false)) ->setIconName(L"melon")->setDescriptionId(IDS_ITEM_MELON_SLICE)->setUseDescriptionId(IDS_DESC_MELON_SLICE);
Item::melon = (new FoodItem(104, 2, FoodConstants::FOOD_SATURATION_LOW, false)) ->setIconName(L"melon_slice")->setDescriptionId(IDS_ITEM_MELON_SLICE)->setUseDescriptionId(IDS_DESC_MELON_SLICE);
Item::seeds_pumpkin = (new SeedItem(105, Tile::pumpkinStem_Id, Tile::farmland_Id)) ->setIconName(L"seeds_pumpkin")->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_pumpkin)->setDescriptionId(IDS_ITEM_PUMPKIN_SEEDS)->setUseDescriptionId(IDS_DESC_PUMPKIN_SEEDS);
Item::seeds_melon = (new SeedItem(106, Tile::melonStem_Id, Tile::farmland_Id)) ->setIconName(L"seeds_melon")->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_melon)->setDescriptionId(IDS_ITEM_MELON_SEEDS)->setUseDescriptionId(IDS_DESC_MELON_SEEDS);
Item::seeds_pumpkin = (new SeedItem(105, Tile::pumpkinStem_Id, Tile::farmland_Id)) ->setIconName(L"pumpkin_seeds")->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_pumpkin)->setDescriptionId(IDS_ITEM_PUMPKIN_SEEDS)->setUseDescriptionId(IDS_DESC_PUMPKIN_SEEDS);
Item::seeds_melon = (new SeedItem(106, Tile::melonStem_Id, Tile::farmland_Id)) ->setIconName(L"melon_seeds")->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_melon)->setDescriptionId(IDS_ITEM_MELON_SEEDS)->setUseDescriptionId(IDS_DESC_MELON_SEEDS);
Item::beef_raw = (new FoodItem(107, 3, FoodConstants::FOOD_SATURATION_LOW, true)) ->setIconName(L"beefRaw")->setDescriptionId(IDS_ITEM_BEEF_RAW)->setUseDescriptionId(IDS_DESC_BEEF_RAW);
Item::beef_cooked = (new FoodItem(108, 8, FoodConstants::FOOD_SATURATION_GOOD, true))->setIconName(L"beefCooked")->setDescriptionId(IDS_ITEM_BEEF_COOKED)->setUseDescriptionId(IDS_DESC_BEEF_COOKED);
Item::chicken_raw = (new FoodItem(109, 2, FoodConstants::FOOD_SATURATION_LOW, true))->setEatEffect(MobEffect::hunger->id, 30, 0, .3f)->setIconName(L"chickenRaw")->setDescriptionId(IDS_ITEM_CHICKEN_RAW)->setUseDescriptionId(IDS_DESC_CHICKEN_RAW);
Item::chicken_cooked = (new FoodItem(110, 6, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"chickenCooked")->setDescriptionId(IDS_ITEM_CHICKEN_COOKED)->setUseDescriptionId(IDS_DESC_CHICKEN_COOKED);
Item::rotten_flesh = (new FoodItem(111, 4, FoodConstants::FOOD_SATURATION_POOR, true))->setEatEffect(MobEffect::hunger->id, 30, 0, .8f)->setIconName(L"rottenFlesh")->setDescriptionId(IDS_ITEM_ROTTEN_FLESH)->setUseDescriptionId(IDS_DESC_ROTTEN_FLESH);
Item::beef_raw = (new FoodItem(107, 3, FoodConstants::FOOD_SATURATION_LOW, true)) ->setIconName(L"beef")->setDescriptionId(IDS_ITEM_BEEF_RAW)->setUseDescriptionId(IDS_DESC_BEEF_RAW);
Item::beef_cooked = (new FoodItem(108, 8, FoodConstants::FOOD_SATURATION_GOOD, true))->setIconName(L"cooked_beef")->setDescriptionId(IDS_ITEM_BEEF_COOKED)->setUseDescriptionId(IDS_DESC_BEEF_COOKED);
Item::chicken_raw = (new FoodItem(109, 2, FoodConstants::FOOD_SATURATION_LOW, true))->setEatEffect(MobEffect::hunger->id, 30, 0, .3f)->setIconName(L"chicken")->setDescriptionId(IDS_ITEM_CHICKEN_RAW)->setUseDescriptionId(IDS_DESC_CHICKEN_RAW);
Item::chicken_cooked = (new FoodItem(110, 6, FoodConstants::FOOD_SATURATION_NORMAL, true))->setIconName(L"cooked_chicken")->setDescriptionId(IDS_ITEM_CHICKEN_COOKED)->setUseDescriptionId(IDS_DESC_CHICKEN_COOKED);
Item::rotten_flesh = (new FoodItem(111, 4, FoodConstants::FOOD_SATURATION_POOR, true))->setEatEffect(MobEffect::hunger->id, 30, 0, .8f)->setIconName(L"rotten_flesh")->setDescriptionId(IDS_ITEM_ROTTEN_FLESH)->setUseDescriptionId(IDS_DESC_ROTTEN_FLESH);
Item::enderPearl = (new EnderpearlItem(112)) ->setIconName(L"enderPearl")->setDescriptionId(IDS_ITEM_ENDER_PEARL)->setUseDescriptionId(IDS_DESC_ENDER_PEARL);
Item::enderPearl = (new EnderpearlItem(112)) ->setIconName(L"ender_pearl")->setDescriptionId(IDS_ITEM_ENDER_PEARL)->setUseDescriptionId(IDS_DESC_ENDER_PEARL);
Item::blazeRod = (new Item(113) ) ->setIconName(L"blazeRod")->setDescriptionId(IDS_ITEM_BLAZE_ROD)->setUseDescriptionId(IDS_DESC_BLAZE_ROD)->handEquipped();
Item::ghastTear = (new Item(114) ) ->setIconName(L"ghastTear")->setDescriptionId(IDS_ITEM_GHAST_TEAR)->setUseDescriptionId(IDS_DESC_GHAST_TEAR)->setPotionBrewingFormula(PotionBrewing::MOD_GHASTTEARS);
Item::goldNugget = (new Item(115) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold)->setIconName(L"goldNugget")->setDescriptionId(IDS_ITEM_GOLD_NUGGET)->setUseDescriptionId(IDS_DESC_GOLD_NUGGET);
Item::blazeRod = (new Item(113) ) ->setIconName(L"blaze_rod")->setDescriptionId(IDS_ITEM_BLAZE_ROD)->setUseDescriptionId(IDS_DESC_BLAZE_ROD)->handEquipped();
Item::ghastTear = (new Item(114) ) ->setIconName(L"ghast_tear")->setDescriptionId(IDS_ITEM_GHAST_TEAR)->setUseDescriptionId(IDS_DESC_GHAST_TEAR)->setPotionBrewingFormula(PotionBrewing::MOD_GHASTTEARS);
Item::goldNugget = (new Item(115) ) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold)->setIconName(L"gold_nugget")->setDescriptionId(IDS_ITEM_GOLD_NUGGET)->setUseDescriptionId(IDS_DESC_GOLD_NUGGET);
Item::netherwart_seeds = (new SeedItem(116, Tile::netherStalk_Id, Tile::soulsand_Id) ) ->setIconName(L"netherStalkSeeds")->setDescriptionId(IDS_ITEM_NETHER_STALK_SEEDS)->setUseDescriptionId(IDS_DESC_NETHER_STALK_SEEDS)->setPotionBrewingFormula(PotionBrewing::MOD_NETHERWART);
Item::netherwart_seeds = (new SeedItem(116, Tile::netherStalk_Id, Tile::soulsand_Id) ) ->setIconName(L"nether_wart")->setDescriptionId(IDS_ITEM_NETHER_STALK_SEEDS)->setUseDescriptionId(IDS_DESC_NETHER_STALK_SEEDS)->setPotionBrewingFormula(PotionBrewing::MOD_NETHERWART);
Item::potion = static_cast<PotionItem *>((new PotionItem(117))->setIconName(L"potion")->setDescriptionId(IDS_ITEM_POTION)->setUseDescriptionId(IDS_DESC_POTION));
Item::glassBottle = (new BottleItem(118) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_glass)->setIconName(L"glassBottle")->setDescriptionId(IDS_ITEM_GLASS_BOTTLE)->setUseDescriptionId(IDS_DESC_GLASS_BOTTLE);
Item::glassBottle = (new BottleItem(118) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_glass)->setIconName(L"glass_bottle")->setDescriptionId(IDS_ITEM_GLASS_BOTTLE)->setUseDescriptionId(IDS_DESC_GLASS_BOTTLE);
Item::spiderEye = (new FoodItem(119, 2, FoodConstants::FOOD_SATURATION_GOOD, false) ) ->setEatEffect(MobEffect::poison->id, 5, 0, 1.0f)->setIconName(L"spiderEye")->setDescriptionId(IDS_ITEM_SPIDER_EYE)->setUseDescriptionId(IDS_DESC_SPIDER_EYE)->setPotionBrewingFormula(PotionBrewing::MOD_SPIDEREYE);
Item::fermentedSpiderEye = (new Item(120) ) ->setIconName(L"fermentedSpiderEye")->setDescriptionId(IDS_ITEM_FERMENTED_SPIDER_EYE)->setUseDescriptionId(IDS_DESC_FERMENTED_SPIDER_EYE)->setPotionBrewingFormula(PotionBrewing::MOD_FERMENTEDEYE);
Item::spiderEye = (new FoodItem(119, 2, FoodConstants::FOOD_SATURATION_GOOD, false) ) ->setEatEffect(MobEffect::poison->id, 5, 0, 1.0f)->setIconName(L"spider_eye")->setDescriptionId(IDS_ITEM_SPIDER_EYE)->setUseDescriptionId(IDS_DESC_SPIDER_EYE)->setPotionBrewingFormula(PotionBrewing::MOD_SPIDEREYE);
Item::fermentedSpiderEye = (new Item(120) ) ->setIconName(L"fermented_spider_eye")->setDescriptionId(IDS_ITEM_FERMENTED_SPIDER_EYE)->setUseDescriptionId(IDS_DESC_FERMENTED_SPIDER_EYE)->setPotionBrewingFormula(PotionBrewing::MOD_FERMENTEDEYE);
Item::blazePowder = (new Item(121) ) ->setIconName(L"blazePowder")->setDescriptionId(IDS_ITEM_BLAZE_POWDER)->setUseDescriptionId(IDS_DESC_BLAZE_POWDER)->setPotionBrewingFormula(PotionBrewing::MOD_BLAZEPOWDER);
Item::magmaCream = (new Item(122) ) ->setIconName(L"magmaCream")->setDescriptionId(IDS_ITEM_MAGMA_CREAM)->setUseDescriptionId(IDS_DESC_MAGMA_CREAM)->setPotionBrewingFormula(PotionBrewing::MOD_MAGMACREAM);
Item::blazePowder = (new Item(121) ) ->setIconName(L"blaze_powder")->setDescriptionId(IDS_ITEM_BLAZE_POWDER)->setUseDescriptionId(IDS_DESC_BLAZE_POWDER)->setPotionBrewingFormula(PotionBrewing::MOD_BLAZEPOWDER);
Item::magmaCream = (new Item(122) ) ->setIconName(L"magma_cream")->setDescriptionId(IDS_ITEM_MAGMA_CREAM)->setUseDescriptionId(IDS_DESC_MAGMA_CREAM)->setPotionBrewingFormula(PotionBrewing::MOD_MAGMACREAM);
Item::brewingStand = (new TilePlanterItem(123, Tile::brewingStand) ) ->setBaseItemTypeAndMaterial(eBaseItemType_device, eMaterial_blaze)->setIconName(L"brewingStand")->setDescriptionId(IDS_ITEM_BREWING_STAND)->setUseDescriptionId(IDS_DESC_BREWING_STAND);
Item::brewingStand = (new TilePlanterItem(123, Tile::brewingStand) ) ->setBaseItemTypeAndMaterial(eBaseItemType_device, eMaterial_blaze)->setIconName(L"brewing_stand")->setDescriptionId(IDS_ITEM_BREWING_STAND)->setUseDescriptionId(IDS_DESC_BREWING_STAND);
Item::cauldron = (new TilePlanterItem(124, Tile::cauldron) ) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_iron)->setIconName(L"cauldron")->setDescriptionId(IDS_ITEM_CAULDRON)->setUseDescriptionId(IDS_DESC_CAULDRON);
Item::eyeOfEnder = (new EnderEyeItem(125) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_ender)->setIconName(L"eyeOfEnder")->setDescriptionId(IDS_ITEM_EYE_OF_ENDER)->setUseDescriptionId(IDS_DESC_EYE_OF_ENDER);
Item::speckledMelon = (new Item(126) ) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_melon)->setIconName(L"speckledMelon")->setDescriptionId(IDS_ITEM_SPECKLED_MELON)->setUseDescriptionId(IDS_DESC_SPECKLED_MELON)->setPotionBrewingFormula(PotionBrewing::MOD_SPECKLEDMELON);
Item::eyeOfEnder = (new EnderEyeItem(125) ) ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_ender)->setIconName(L"ender_eye")->setDescriptionId(IDS_ITEM_EYE_OF_ENDER)->setUseDescriptionId(IDS_DESC_EYE_OF_ENDER);
Item::speckledMelon = (new Item(126) ) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_melon)->setIconName(L"glistering_melon_slice")->setDescriptionId(IDS_ITEM_SPECKLED_MELON)->setUseDescriptionId(IDS_DESC_SPECKLED_MELON)->setPotionBrewingFormula(PotionBrewing::MOD_SPECKLEDMELON);
Item::spawnEgg = (new SpawnEggItem(127)) ->setIconName(L"monsterPlacer")->setDescriptionId(IDS_ITEM_MONSTER_SPAWNER)->setUseDescriptionId(IDS_DESC_MONSTER_SPAWNER);
Item::spawnEgg = (new SpawnEggItem(127)) ->setIconName(L"spawn_egg")->setDescriptionId(IDS_ITEM_MONSTER_SPAWNER)->setUseDescriptionId(IDS_DESC_MONSTER_SPAWNER);
// 4J Stu - Brought this forward
Item::expBottle = (new ExperienceItem(128)) ->setIconName(L"expBottle")->setDescriptionId(IDS_ITEM_EXP_BOTTLE)->setUseDescriptionId(IDS_DESC_EXP_BOTTLE);
Item::expBottle = (new ExperienceItem(128)) ->setIconName(L"experience_bottle")->setDescriptionId(IDS_ITEM_EXP_BOTTLE)->setUseDescriptionId(IDS_DESC_EXP_BOTTLE);
Item::record_01 = ( new RecordingItem(2000, L"13") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_01)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_02 = ( new RecordingItem(2001, L"cat") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_02)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_01 = ( new RecordingItem(2000, L"13") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_01)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_02 = ( new RecordingItem(2001, L"cat") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_02)->setUseDescriptionId(IDS_DESC_RECORD);
// 4J - new records brought forward from 1.2.3
Item::record_03 = ( new RecordingItem(2002, L"blocks") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_03)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_04 = ( new RecordingItem(2003, L"chirp") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_04)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_05 = ( new RecordingItem(2004, L"far") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_05)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_06 = ( new RecordingItem(2005, L"mall") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_06)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_07 = ( new RecordingItem(2006, L"mellohi") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_07)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_09 = ( new RecordingItem(2007, L"stal") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_08)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_10 = ( new RecordingItem(2008, L"strad") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_09)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_11 = ( new RecordingItem(2009, L"ward") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_10)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_12 = ( new RecordingItem(2010, L"11") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_11)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_08 = ( new RecordingItem(2011, L"where are we now") ) ->setIconName(L"record")->setDescriptionId(IDS_ITEM_RECORD_12)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_03 = ( new RecordingItem(2002, L"blocks") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_03)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_04 = ( new RecordingItem(2003, L"chirp") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_04)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_05 = ( new RecordingItem(2004, L"far") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_05)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_06 = ( new RecordingItem(2005, L"mall") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_06)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_07 = ( new RecordingItem(2006, L"mellohi") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_07)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_09 = ( new RecordingItem(2007, L"stal") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_08)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_10 = ( new RecordingItem(2008, L"strad") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_09)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_11 = ( new RecordingItem(2009, L"ward") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_10)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_12 = ( new RecordingItem(2010, L"11") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_11)->setUseDescriptionId(IDS_DESC_RECORD);
Item::record_08 = ( new RecordingItem(2011, L"where are we now") ) ->setIconName(L"music_disc")->setDescriptionId(IDS_ITEM_RECORD_12)->setUseDescriptionId(IDS_DESC_RECORD);
// TU9
// putting the fire charge in as a torch, so that it stacks without being near the middle of the selection boxes
Item::fireball = (new FireChargeItem(129)) ->setBaseItemTypeAndMaterial(eBaseItemType_torch, eMaterial_setfire)->setIconName(L"fireball")->setDescriptionId(IDS_ITEM_FIREBALL)->setUseDescriptionId(IDS_DESC_FIREBALL);
Item::frame = (new HangingEntityItem(133,eTYPE_ITEM_FRAME)) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_glass)->setIconName(L"frame")->setDescriptionId(IDS_ITEM_ITEMFRAME)->setUseDescriptionId(IDS_DESC_ITEMFRAME);
Item::fireball = (new FireChargeItem(129)) ->setBaseItemTypeAndMaterial(eBaseItemType_torch, eMaterial_setfire)->setIconName(L"fire_charge")->setDescriptionId(IDS_ITEM_FIREBALL)->setUseDescriptionId(IDS_DESC_FIREBALL);
Item::frame = (new HangingEntityItem(133,eTYPE_ITEM_FRAME)) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_glass)->setIconName(L"item_frame")->setDescriptionId(IDS_ITEM_ITEMFRAME)->setUseDescriptionId(IDS_DESC_ITEMFRAME);
// TU12
@ -466,31 +466,31 @@ void Item::staticCtor()
Item::emerald = (new Item(132)) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_emerald)->setIconName(L"emerald")->setDescriptionId(IDS_ITEM_EMERALD)->setUseDescriptionId(IDS_DESC_EMERALD);
Item::flowerPot = (new TilePlanterItem(134, Tile::flowerPot)) ->setIconName(L"flowerPot")->setDescriptionId(IDS_FLOWERPOT)->setUseDescriptionId(IDS_DESC_FLOWERPOT);
Item::flowerPot = (new TilePlanterItem(134, Tile::flowerPot)) ->setIconName(L"flower_pot")->setDescriptionId(IDS_FLOWERPOT)->setUseDescriptionId(IDS_DESC_FLOWERPOT);
Item::carrots = (new SeedFoodItem(135, 4, FoodConstants::FOOD_SATURATION_NORMAL, Tile::carrots_Id, Tile::farmland_Id)) ->setIconName(L"carrots")->setDescriptionId(IDS_CARROTS)->setUseDescriptionId(IDS_DESC_CARROTS);
Item::carrots = (new SeedFoodItem(135, 4, FoodConstants::FOOD_SATURATION_NORMAL, Tile::carrots_Id, Tile::farmland_Id)) ->setIconName(L"carrot")->setDescriptionId(IDS_CARROTS)->setUseDescriptionId(IDS_DESC_CARROTS);
Item::potato = (new SeedFoodItem(136, 1, FoodConstants::FOOD_SATURATION_LOW, Tile::potatoes_Id, Tile::farmland_Id)) ->setIconName(L"potato")->setDescriptionId(IDS_POTATO)->setUseDescriptionId(IDS_DESC_POTATO);
Item::potatoBaked = (new FoodItem(137, 6, FoodConstants::FOOD_SATURATION_NORMAL, false)) ->setIconName(L"potatoBaked")->setDescriptionId(IDS_ITEM_POTATO_BAKED)->setUseDescriptionId(IDS_DESC_POTATO_BAKED);
Item::potatoPoisonous = (new FoodItem(138, 2, FoodConstants::FOOD_SATURATION_LOW, false)) ->setEatEffect(MobEffect::poison->id, 5, 0, .6f)->setIconName(L"potatoPoisonous")->setDescriptionId(IDS_ITEM_POTATO_POISONOUS)->setUseDescriptionId(IDS_DESC_POTATO_POISONOUS);
Item::potatoBaked = (new FoodItem(137, 6, FoodConstants::FOOD_SATURATION_NORMAL, false)) ->setIconName(L"baked_potato")->setDescriptionId(IDS_ITEM_POTATO_BAKED)->setUseDescriptionId(IDS_DESC_POTATO_BAKED);
Item::potatoPoisonous = (new FoodItem(138, 2, FoodConstants::FOOD_SATURATION_LOW, false)) ->setEatEffect(MobEffect::poison->id, 5, 0, .6f)->setIconName(L"poisonous_potato")->setDescriptionId(IDS_ITEM_POTATO_POISONOUS)->setUseDescriptionId(IDS_DESC_POTATO_POISONOUS);
Item::emptyMap = static_cast<EmptyMapItem *>((new EmptyMapItem(139))->setIconName(L"map_empty")->setDescriptionId(IDS_ITEM_MAP_EMPTY)->setUseDescriptionId(IDS_DESC_MAP_EMPTY));
Item::emptyMap = static_cast<EmptyMapItem *>((new EmptyMapItem(139))->setIconName(L"map")->setDescriptionId(IDS_ITEM_MAP_EMPTY)->setUseDescriptionId(IDS_DESC_MAP_EMPTY));
Item::carrotGolden = (new FoodItem(140, 6, FoodConstants::FOOD_SATURATION_SUPERNATURAL, false)) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_carrot)->setIconName(L"carrotGolden")->setPotionBrewingFormula(PotionBrewing::MOD_GOLDENCARROT)->setDescriptionId(IDS_ITEM_CARROT_GOLDEN)->setUseDescriptionId(IDS_DESC_CARROT_GOLDEN);
Item::carrotGolden = (new FoodItem(140, 6, FoodConstants::FOOD_SATURATION_SUPERNATURAL, false)) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_carrot)->setIconName(L"golden_carrot")->setPotionBrewingFormula(PotionBrewing::MOD_GOLDENCARROT)->setDescriptionId(IDS_ITEM_CARROT_GOLDEN)->setUseDescriptionId(IDS_DESC_CARROT_GOLDEN);
Item::carrotOnAStick = (new CarrotOnAStickItem(142)) ->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_carrot)->setIconName(L"carrotOnAStick")->setDescriptionId(IDS_ITEM_CARROT_ON_A_STICK)->setUseDescriptionId(IDS_DESC_CARROT_ON_A_STICK);
Item::carrotOnAStick = (new CarrotOnAStickItem(142)) ->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_carrot)->setIconName(L"carrot_on_a_stick")->setDescriptionId(IDS_ITEM_CARROT_ON_A_STICK)->setUseDescriptionId(IDS_DESC_CARROT_ON_A_STICK);
Item::netherStar = (new SimpleFoiledItem(143)) ->setIconName(L"nether_star")->setDescriptionId(IDS_NETHER_STAR)->setUseDescriptionId(IDS_DESC_NETHER_STAR);
Item::pumpkinPie = (new FoodItem(144, 8, FoodConstants::FOOD_SATURATION_LOW, false)) ->setIconName(L"pumpkinPie")->setDescriptionId(IDS_ITEM_PUMPKIN_PIE)->setUseDescriptionId(IDS_DESC_PUMPKIN_PIE);
Item::fireworks = (new FireworksItem(145)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fireworks, Item::eMaterial_undefined)->setIconName(L"fireworks")->setDescriptionId(IDS_FIREWORKS)->setUseDescriptionId(IDS_DESC_FIREWORKS);
Item::pumpkinPie = (new FoodItem(144, 8, FoodConstants::FOOD_SATURATION_LOW, false)) ->setIconName(L"pumpkin_pie")->setDescriptionId(IDS_ITEM_PUMPKIN_PIE)->setUseDescriptionId(IDS_DESC_PUMPKIN_PIE);
Item::fireworks = (new FireworksItem(145)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fireworks, Item::eMaterial_undefined)->setIconName(L"firework_rocket")->setDescriptionId(IDS_FIREWORKS)->setUseDescriptionId(IDS_DESC_FIREWORKS);
Item::fireworksCharge = (new FireworksChargeItem(146)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fireworks, Item::eMaterial_undefined)->setIconName(L"fireworks_charge")->setDescriptionId(IDS_FIREWORKS_CHARGE)->setUseDescriptionId(IDS_DESC_FIREWORKS_CHARGE);
EnchantedBookItem::enchantedBook = static_cast<EnchantedBookItem *>((new EnchantedBookItem(147))->setMaxStackSize(1)->setIconName(L"enchantedBook")->setDescriptionId(IDS_ITEM_ENCHANTED_BOOK)->setUseDescriptionId(IDS_DESC_ENCHANTED_BOOK));
EnchantedBookItem::enchantedBook = static_cast<EnchantedBookItem *>((new EnchantedBookItem(147))->setMaxStackSize(1)->setIconName(L"enchanted_book")->setDescriptionId(IDS_ITEM_ENCHANTED_BOOK)->setUseDescriptionId(IDS_DESC_ENCHANTED_BOOK));
Item::comparator = (new TilePlanterItem(148, Tile::comparator_off)) ->setIconName(L"comparator")->setDescriptionId(IDS_ITEM_COMPARATOR)->setUseDescriptionId(IDS_DESC_COMPARATOR);
Item::netherbrick = (new Item(149)) ->setIconName(L"netherbrick")->setDescriptionId(IDS_ITEM_NETHERBRICK)->setUseDescriptionId(IDS_DESC_ITEM_NETHERBRICK);
Item::netherQuartz = (new Item(150)) ->setIconName(L"netherquartz")->setDescriptionId(IDS_ITEM_NETHER_QUARTZ)->setUseDescriptionId(IDS_DESC_NETHER_QUARTZ);
Item::minecart_tnt = (new MinecartItem(151, Minecart::TYPE_TNT)) ->setIconName(L"minecart_tnt")->setDescriptionId(IDS_ITEM_MINECART_TNT)->setUseDescriptionId(IDS_DESC_MINECART_TNT);
Item::minecart_hopper = (new MinecartItem(152, Minecart::TYPE_HOPPER)) ->setIconName(L"minecart_hopper")->setDescriptionId(IDS_ITEM_MINECART_HOPPER)->setUseDescriptionId(IDS_DESC_MINECART_HOPPER);
Item::netherbrick = (new Item(149)) ->setIconName(L"nether_brick")->setDescriptionId(IDS_ITEM_NETHERBRICK)->setUseDescriptionId(IDS_DESC_ITEM_NETHERBRICK);
Item::netherQuartz = (new Item(150)) ->setIconName(L"quartz")->setDescriptionId(IDS_ITEM_NETHER_QUARTZ)->setUseDescriptionId(IDS_DESC_NETHER_QUARTZ);
Item::minecart_tnt = (new MinecartItem(151, Minecart::TYPE_TNT)) ->setIconName(L"tnt_minecart")->setDescriptionId(IDS_ITEM_MINECART_TNT)->setUseDescriptionId(IDS_DESC_MINECART_TNT);
Item::minecart_hopper = (new MinecartItem(152, Minecart::TYPE_HOPPER)) ->setIconName(L"hopper_minecart")->setDescriptionId(IDS_ITEM_MINECART_HOPPER)->setUseDescriptionId(IDS_DESC_MINECART_HOPPER);
Item::horseArmorMetal = (new Item(161)) ->setIconName(L"iron_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_IRON_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_IRON_HORSE_ARMOR);
Item::horseArmorGold = (new Item(162)) ->setIconName(L"gold_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_GOLD_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_GOLD_HORSE_ARMOR);
Item::horseArmorGold = (new Item(162)) ->setIconName(L"golden_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_GOLD_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_GOLD_HORSE_ARMOR);
Item::horseArmorDiamond = (new Item(163)) ->setIconName(L"diamond_horse_armor")->setMaxStackSize(1)->setDescriptionId(IDS_ITEM_DIAMOND_HORSE_ARMOR)->setUseDescriptionId(IDS_DESC_DIAMOND_HORSE_ARMOR);
Item::lead = (new LeashItem(164)) ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_undefined)->setIconName(L"lead")->setDescriptionId(IDS_ITEM_LEAD)->setUseDescriptionId(IDS_DESC_LEAD);
Item::nameTag = (new NameTagItem(165)) ->setIconName(L"name_tag")->setDescriptionId(IDS_ITEM_NAME_TAG)->setUseDescriptionId(IDS_DESC_NAME_TAG);}

View file

@ -6,6 +6,7 @@
#include "net.minecraft.world.item.h"
#include "net.minecraft.stats.h"
#include "net.minecraft.world.h"
#include "WoodTile.h"
const unsigned int LeafTile::LEAF_NAMES[LEAF_NAMES_LENGTH] = { IDS_TILE_LEAVES_OAK,
IDS_TILE_LEAVES_SPRUCE,
@ -349,10 +350,13 @@ void LeafTile::registerIcons(IconRegister *iconRegister)
for (int fancy = 0; fancy < 2; fancy++)
{
//icons[fancy] = new Icon[TEXTURES[fancy].length];
auto wood = (WoodTile*)Tile::wood;
auto woodNames = wood->TEXTURE_NAMES;
for (int i = 0; i < 4; i++)
for (int i = 0; i < wood->WOOD_NAMES_LENGTH; i++)
{
icons[fancy][i] = iconRegister->registerIcon(TEXTURES[fancy][i]);
auto iconName = i != 2 ? woodNames[i] : woodNames[0];
icons[fancy][i] = iconRegister->registerIcon(iconName + L"_leaves" + (fancy == 1 ? L"_opaque" : L""));
}
}
}

View file

@ -29,9 +29,9 @@ Icon *MycelTile::getTexture(LevelSource *level, int x, int y, int z, int face)
void MycelTile::registerIcons(IconRegister *iconRegister)
{
icon = iconRegister->registerIcon(L"mycel_side");
iconTop = iconRegister->registerIcon(L"mycel_top");
iconSnowSide = iconRegister->registerIcon(L"snow_side");
icon = iconRegister->registerIcon(getIconName() + L"_side");
iconTop = iconRegister->registerIcon(getIconName() + L"_top");
iconSnowSide = iconRegister->registerIcon(L"grass_block_snow");
}
void MycelTile::tick(Level *level, int x, int y, int z, Random *random)

View file

@ -107,6 +107,6 @@ void NetherWartTile::registerIcons(IconRegister *iconRegister)
{
for (int i = 0; i < NETHER_STALK_TEXTURE_COUNT; i++)
{
icons[i] = iconRegister->registerIcon(getIconName() + L"_stage_" + std::to_wstring(i) );
icons[i] = iconRegister->registerIcon(getIconName() + L"_stage" + std::to_wstring(i) );
}
}

View file

@ -15,7 +15,7 @@ const wstring PistonBaseTile::EDGE_TEX = L"piston_side";
const wstring PistonBaseTile::PLATFORM_TEX = L"piston_top";
const wstring PistonBaseTile::PLATFORM_STICKY_TEX = L"piston_top_sticky";
const wstring PistonBaseTile::BACK_TEX = L"piston_bottom";
const wstring PistonBaseTile::INSIDE_TEX = L"piston_inner_top";
const wstring PistonBaseTile::INSIDE_TEX = L"piston_inner";
const float PistonBaseTile::PLATFORM_THICKNESS = 4.0f;

View file

@ -6,6 +6,7 @@
PotatoTile::PotatoTile(int id) : CropTile(id)
{
stages = 4;
}
Icon *PotatoTile::getTexture(int face, int data)
@ -49,12 +50,4 @@ void PotatoTile::spawnResources(Level *level, int x, int y, int z, int data, flo
popResource(level, x, y, z, std::make_shared<ItemInstance>(Item::potatoPoisonous));
}
}
}
void PotatoTile::registerIcons(IconRegister *iconRegister)
{
for (int i = 0; i < 4; i++)
{
icons[i] = iconRegister->registerIcon(getIconName() + L"_stage_" + std::to_wstring(i) );
}
}

View file

@ -19,5 +19,4 @@ protected:
public:
void spawnResources(Level *level, int x, int y, int z, int data, float odds, int playerBonus);
void registerIcons(IconRegister *iconRegister);
};

View file

@ -14,8 +14,8 @@
#include "SoundTypes.h"
const wstring PotionItem::DEFAULT_ICON = L"potion";
const wstring PotionItem::THROWABLE_ICON = L"potion_splash";
const wstring PotionItem::CONTENTS_ICON = L"potion_contents";
const wstring PotionItem::THROWABLE_ICON = L"splash_potion";
const wstring PotionItem::CONTENTS_ICON = L"potion_overlay";
// 4J Added
vector<pair<int, int> > PotionItem::s_uniquePotionValues;

View file

@ -22,7 +22,7 @@ Icon *PoweredRailTile::getTexture(int face, int data)
void PoweredRailTile::registerIcons(IconRegister *iconRegister)
{
BaseRailTile::registerIcons(iconRegister);
iconPowered = iconRegister->registerIcon(getIconName() + L"_powered");
iconPowered = iconRegister->registerIcon(getIconName() + L"_on");
}
bool PoweredRailTile::findPoweredRailSignal(Level *level, int x, int y, int z, int data, bool forward, int searchDepth)

View file

@ -163,7 +163,7 @@ void PumpkinTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptr<Livi
void PumpkinTile::registerIcons(IconRegister *iconRegister)
{
iconFace = iconRegister->registerIcon(getIconName() + L"_face_" + (lit ? L"on" : L"off"));
iconFace = iconRegister->registerIcon((lit ? L"jack_o_lantern" : L"carved_" + getIconName()));
iconTop = iconRegister->registerIcon(getIconName() + L"_top");
icon = iconRegister->registerIcon(getIconName() + L"_side");
}

View file

@ -13,10 +13,10 @@ public:
static const int DIR_WEST = 1;
static const int DIR_NORTH = 2;
static const int DIR_EAST = 3;
private:
static const wstring TEXTURE_FACE;
static const wstring TEXTURE_LANTERN;
private:
bool lit;
Icon *iconTop;
Icon *iconFace;

View file

@ -14,9 +14,9 @@ int QuartzBlockTile::BLOCK_NAMES[QUARTZ_BLOCK_NAMES] = {
const wstring QuartzBlockTile::TEXTURE_TOP = L"top";
const wstring QuartzBlockTile::TEXTURE_CHISELED_TOP = L"chiseled_top";
const wstring QuartzBlockTile::TEXTURE_LINES_TOP = L"lines_top";
const wstring QuartzBlockTile::TEXTURE_LINES_TOP = L"pillar_top";
const wstring QuartzBlockTile::TEXTURE_BOTTOM = L"bottom";
const wstring QuartzBlockTile::TEXTURE_NAMES[QUARTZ_BLOCK_TEXTURES] = { L"side", L"chiseled", L"lines", L"", L""};
const wstring QuartzBlockTile::TEXTURE_NAMES[QUARTZ_BLOCK_TEXTURES] = { L"side", L"chiseled", L"pillar", L"", L""};
QuartzBlockTile::QuartzBlockTile(int id) : Tile(id, Material::stone)
{
@ -103,20 +103,20 @@ int QuartzBlockTile::getRenderShape()
void QuartzBlockTile::registerIcons(IconRegister *iconRegister)
{
icons[0] = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_NAMES[0]); // side
icons[1] = iconRegister->registerIcon(TEXTURE_NAMES[1] + L"_" + getIconName()); // chiseled
icons[2] = iconRegister->registerIcon(L"quartz_" + TEXTURE_NAMES[2]); // pillar
for (int i = 0; i < QUARTZ_BLOCK_TEXTURES; i++)
{
if (TEXTURE_NAMES[i].empty())
{
icons[i] = icons[i - 1];
}
else
{
icons[i] = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_NAMES[i]);
}
}
iconTop = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_TOP);
iconChiseledTop = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_CHISELED_TOP);
iconLinesTop = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_LINES_TOP);
iconChiseledTop = iconRegister->registerIcon(L"chiseled_" + getIconName() + L"_top");
iconLinesTop = iconRegister->registerIcon(L"quartz_" + TEXTURE_LINES_TOP);
iconBottom = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_BOTTOM);
}

View file

@ -21,7 +21,7 @@ Icon *RailTile::getTexture(int face, int data)
void RailTile::registerIcons(IconRegister *iconRegister)
{
BaseRailTile::registerIcons(iconRegister);
iconTurn = iconRegister->registerIcon(getIconName() + L"_turned");
iconTurn = iconRegister->registerIcon(getIconName() + L"_corner");
}
void RailTile::updateState(Level *level, int x, int y, int z, int data, int dir, int type)

View file

@ -61,7 +61,7 @@ const Rarity *RecordingItem::getRarity(shared_ptr<ItemInstance> itemInstance)
void RecordingItem::registerIcons(IconRegister *iconRegister)
{
icon = iconRegister->registerIcon(L"record_" + recording);
icon = iconRegister->registerIcon(getIconName() + L"_" + recording);
}
RecordingItem *RecordingItem::getByName(const wstring &name)

View file

@ -16,14 +16,7 @@ RedlightTile::RedlightTile(int id, bool isLit) : Tile(id, Material::buildable_gl
void RedlightTile::registerIcons(IconRegister *iconRegister)
{
if (isLit)
{
icon = iconRegister->registerIcon(L"redstoneLight_lit");
}
else
{
icon = iconRegister->registerIcon(L"redstoneLight");
}
icon = iconRegister->registerIcon(getIconName());
}
void RedlightTile::onPlace(Level *level, int x, int y, int z)

View file

@ -6,7 +6,7 @@
const wstring SandStoneTile::TEXTURE_TOP = L"sandstone_top";
const wstring SandStoneTile::TEXTURE_BOTTOM = L"sandstone_bottom";
const wstring SandStoneTile::TEXTURE_NAMES[] = {L"sandstone_side", L"sandstone_carved", L"sandstone_smooth"};
const wstring SandStoneTile::TEXTURE_NAMES[] = {L"sandstone", L"chiseled_sandstone", L"cut_sandstone"};
int SandStoneTile::SANDSTONE_NAMES[SANDSTONE_BLOCK_NAMES] = {
IDS_TILE_SANDSTONE, IDS_TILE_SANDSTONE_CHISELED, IDS_TILE_SANDSTONE_SMOOTH

Some files were not shown because too many files have changed in this diff Show more