diff --git a/Minecraft.Client/AbstractTexturePack.cpp b/Minecraft.Client/AbstractTexturePack.cpp index a3c677272e..9f0da0d37a 100644 --- a/Minecraft.Client/AbstractTexturePack.cpp +++ b/Minecraft.Client/AbstractTexturePack.cpp @@ -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 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(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(workTex->getData()); + auto bedPix = reinterpret_cast(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 item, Pixel* ogAtlas, pair ogDimensions) { + auto preStitched = static_cast(item.second); + + auto imag = new BufferedImage(texSize, texSize, GL_RGBA); + auto pixels = reinterpret_cast(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 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(defaultAtlas->getData()); + + colCount = 16; + rowCount = 32; + + resW = colCount * texSize; + resH = rowCount * texSize; + + terrainAtlas = std::make_unique(resW, resH, 0); + atlas = terrainAtlas.get(); + atlasPixels = reinterpret_cast(atlas->getData()); + + for (auto &i : texturesByName) { + auto preStitched = static_cast(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(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(defaultAtlas->getData()); + + colCount = rowCount = 16; + + resW = colCount * texSize; + resH = rowCount * texSize; + + itemAtlas = std::make_unique(resW, resH, 0); + atlas = itemAtlas.get(); + atlasPixels = reinterpret_cast(atlas->getData()); + + for (auto& i : texturesByName) { + auto preStitched = static_cast(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(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(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; diff --git a/Minecraft.Client/AbstractTexturePack.h b/Minecraft.Client/AbstractTexturePack.h index 6386ecf1e4..642f397571 100644 --- a/Minecraft.Client/AbstractTexturePack.h +++ b/Minecraft.Client/AbstractTexturePack.h @@ -1,15 +1,19 @@ #pragma once -using namespace std; - +#include #include "TexturePack.h" class BufferedImage; +union Pixel; class AbstractTexturePack : public TexturePack { +public: + static const unordered_map INDEXED_TO_JAVA_MAP; + private: const DWORD id; const wstring name; + int texSize; protected: File *file; @@ -28,9 +32,10 @@ class AbstractTexturePack : public TexturePack TexturePack *fallback; ColourTable *m_colourTable; - -protected: + BufferedImage *iconImage; + std::unique_ptr terrainAtlas, itemAtlas, bedTexCache; + BufferedImage* AbstractTexturePack::grabFromDefault(pair item, Pixel* ogAtlas, pair ogDimensions); private: int textureId; @@ -46,6 +51,7 @@ class AbstractTexturePack : public TexturePack 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 @@ class AbstractTexturePack : public TexturePack 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 texturesByName); protected: virtual wstring getAnimationString(const wstring &textureName, const wstring &path); diff --git a/Minecraft.Client/BufferedImage.cpp b/Minecraft.Client/BufferedImage.cpp index 8777d307bd..87c5ddf3f5 100644 --- a/Minecraft.Client/BufferedImage.cpp +++ b/Minecraft.Client/BufferedImage.cpp @@ -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) diff --git a/Minecraft.Client/BufferedImage.h b/Minecraft.Client/BufferedImage.h index 3a08383fc6..4f259ba97f 100644 --- a/Minecraft.Client/BufferedImage.h +++ b/Minecraft.Client/BufferedImage.h @@ -1,9 +1,20 @@ #pragma once +#include 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: diff --git a/Minecraft.Client/CMakeLists.txt b/Minecraft.Client/CMakeLists.txt index 9f75efd219..62461b79f0 100644 --- a/Minecraft.Client/CMakeLists.txt +++ b/Minecraft.Client/CMakeLists.txt @@ -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" > $<$>: # 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" > ) diff --git a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.cpp b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.cpp index 2af1826cf1..1c08999e99 100644 --- a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.cpp +++ b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.cpp @@ -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 diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Common/Network/GameNetworkManager.cpp index 50aeae689e..be51ff2408 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/GameNetworkManager.cpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bit7z.hpp b/Minecraft.Client/Common/libs/bit7z/include/bit7z.hpp new file mode 100644 index 0000000000..ac3afd8ea8 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bit7z.hpp @@ -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 + diff --git a/Minecraft.Client/Common/libs/bit7z/include/bit7zlibrary.hpp b/Minecraft.Client/Common/libs/bit7z/include/bit7zlibrary.hpp new file mode 100644 index 0000000000..652b5b6b07 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bit7zlibrary.hpp @@ -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 + +#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 = ""; +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitabstractarchivecreator.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitabstractarchivecreator.hpp new file mode 100644 index 0000000000..4911d53d54 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitabstractarchivecreator.hpp @@ -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 +#include + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitabstractarchivehandler.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitabstractarchivehandler.hpp new file mode 100644 index 0000000000..8b0a176c2c --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitabstractarchivehandler.hpp @@ -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 +#include + +#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((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((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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitabstractarchiveopener.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitabstractarchiveopener.hpp new file mode 100644 index 0000000000..91adc0fc83 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitabstractarchiveopener.hpp @@ -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 +#include + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitarchiveeditor.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitarchiveeditor.hpp new file mode 100644 index 0000000000..0e47ddb4a2 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitarchiveeditor.hpp @@ -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 + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitarchiveitem.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitarchiveitem.hpp new file mode 100644 index 0000000000..1300d1a40a --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitarchiveitem.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitarchiveiteminfo.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitarchiveiteminfo.hpp new file mode 100644 index 0000000000..dafbc6ce87 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitarchiveiteminfo.hpp @@ -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 + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitarchiveitemoffset.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitarchiveitemoffset.hpp new file mode 100644 index 0000000000..a7983d8d1a --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitarchiveitemoffset.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitarchivereader.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitarchivereader.hpp new file mode 100644 index 0000000000..f0b4bdcc83 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitarchivereader.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitarchivewriter.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitarchivewriter.hpp new file mode 100644 index 0000000000..080b62f682 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitarchivewriter.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitcompressionlevel.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitcompressionlevel.hpp new file mode 100644 index 0000000000..b742f9b111 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitcompressionlevel.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitcompressionmethod.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitcompressionmethod.hpp new file mode 100644 index 0000000000..3f3b6f826b --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitcompressionmethod.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitcompressor.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitcompressor.hpp new file mode 100644 index 0000000000..7ce8f6109b --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitcompressor.hpp @@ -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 + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitdefines.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitdefines.hpp new file mode 100644 index 0000000000..550885c39d --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitdefines.hpp @@ -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( ) +# 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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/biterror.hpp b/Minecraft.Client/Common/libs/bit7z/include/biterror.hpp new file mode 100644 index 0000000000..988a8c7d8f --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/biterror.hpp @@ -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 + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitexception.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitexception.hpp new file mode 100644 index 0000000000..8a272c73a8 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitexception.hpp @@ -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 +#include + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitextractor.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitextractor.hpp new file mode 100644 index 0000000000..e92e2515c0 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitextractor.hpp @@ -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 + +#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, [ ®exFilter ]( 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, + [ ®exFilter ]( 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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitfilecompressor.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitfilecompressor.hpp new file mode 100644 index 0000000000..dffcf9e03b --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitfilecompressor.hpp @@ -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 +#include +#include + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitfileextractor.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitfileextractor.hpp new file mode 100644 index 0000000000..4352196f18 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitfileextractor.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitformat.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitformat.hpp new file mode 100644 index 0000000000..d0d12b6a03 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitformat.hpp @@ -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 +#include + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitfs.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitfs.hpp new file mode 100644 index 0000000000..7dcba6743f --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitfs.hpp @@ -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 +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitgenericitem.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitgenericitem.hpp new file mode 100644 index 0000000000..cbd52509e5 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitgenericitem.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitinputarchive.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitinputarchive.hpp new file mode 100644 index 0000000000..9387d038fe --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitinputarchive.hpp @@ -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 +#include + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bititemsvector.hpp b/Minecraft.Client/Common/libs/bit7z/include/bititemsvector.hpp new file mode 100644 index 0000000000..aac5bc8ee1 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bititemsvector.hpp @@ -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 +#include + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitmemcompressor.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitmemcompressor.hpp new file mode 100644 index 0000000000..ec35dd6aae --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitmemcompressor.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitmemextractor.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitmemextractor.hpp new file mode 100644 index 0000000000..bd1e134d55 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitmemextractor.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitoutputarchive.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitoutputarchive.hpp new file mode 100644 index 0000000000..5f49d5683f --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitoutputarchive.hpp @@ -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 +#include + +#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 + . + * 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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitpropvariant.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitpropvariant.hpp new file mode 100644 index 0000000000..6c0c7a4b01 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitpropvariant.hpp @@ -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 +#include + +#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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitstreamcompressor.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitstreamcompressor.hpp new file mode 100644 index 0000000000..ea735b47f9 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitstreamcompressor.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitstreamextractor.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitstreamextractor.hpp new file mode 100644 index 0000000000..ae36435f5c --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitstreamextractor.hpp @@ -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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bittypes.hpp b/Minecraft.Client/Common/libs/bit7z/include/bittypes.hpp new file mode 100644 index 0000000000..b190032034 --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bittypes.hpp @@ -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 +#include + +// 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 +#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::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 diff --git a/Minecraft.Client/Common/libs/bit7z/include/bitwindows.hpp b/Minecraft.Client/Common/libs/bit7z/include/bitwindows.hpp new file mode 100644 index 0000000000..3a360aa02f --- /dev/null +++ b/Minecraft.Client/Common/libs/bit7z/include/bitwindows.hpp @@ -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 +#include +#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 +#include +#include + +// 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 diff --git a/Minecraft.Client/Common/libs/bit7z/lib/x64/Debug/bit7z.lib b/Minecraft.Client/Common/libs/bit7z/lib/x64/Debug/bit7z.lib new file mode 100644 index 0000000000..162bf8eb9f Binary files /dev/null and b/Minecraft.Client/Common/libs/bit7z/lib/x64/Debug/bit7z.lib differ diff --git a/Minecraft.Client/Common/libs/bit7z/lib/x64/Debug/bit7z.pdb b/Minecraft.Client/Common/libs/bit7z/lib/x64/Debug/bit7z.pdb new file mode 100644 index 0000000000..c956c470ea Binary files /dev/null and b/Minecraft.Client/Common/libs/bit7z/lib/x64/Debug/bit7z.pdb differ diff --git a/Minecraft.Client/Common/libs/bit7z/lib/x64/Release/bit7z.lib b/Minecraft.Client/Common/libs/bit7z/lib/x64/Release/bit7z.lib new file mode 100644 index 0000000000..3f0a728419 Binary files /dev/null and b/Minecraft.Client/Common/libs/bit7z/lib/x64/Release/bit7z.lib differ diff --git a/Minecraft.Client/DLCTexturePack.cpp b/Minecraft.Client/DLCTexturePack.cpp index f1304a9ef5..4fb4e0175c 100644 --- a/Minecraft.Client/DLCTexturePack.cpp +++ b/Minecraft.Client/DLCTexturePack.cpp @@ -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 diff --git a/Minecraft.Client/FileTexturePack.cpp b/Minecraft.Client/FileTexturePack.cpp index 711f673624..4c2a080672 100644 --- a/Minecraft.Client/FileTexturePack.cpp +++ b/Minecraft.Client/FileTexturePack.cpp @@ -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(file); } bool FileTexturePack::isTerrainUpdateCompatible() diff --git a/Minecraft.Client/FileTexturePack.h b/Minecraft.Client/FileTexturePack.h index 85221d1147..c7927f3d1e 100644 --- a/Minecraft.Client/FileTexturePack.h +++ b/Minecraft.Client/FileTexturePack.h @@ -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; + std::vector _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(); diff --git a/Minecraft.Client/FolderTexturePack.cpp b/Minecraft.Client/FolderTexturePack.cpp index 05feca664b..d11f47ce16 100644 --- a/Minecraft.Client/FolderTexturePack.cpp +++ b/Minecraft.Client/FolderTexturePack.cpp @@ -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"); } +} - return new BufferedInputStream(new FileInputStream(file)); -#endif +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 wDrive = L""; +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 result; +} + +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() diff --git a/Minecraft.Client/FolderTexturePack.h b/Minecraft.Client/FolderTexturePack.h index 4327698d53..8b38eca054 100644 --- a/Minecraft.Client/FolderTexturePack.h +++ b/Minecraft.Client/FolderTexturePack.h @@ -6,19 +6,30 @@ class FolderTexturePack : public AbstractTexturePack { private: bool bUILoaded; + unordered_map _cachedFiles; + vector _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(); diff --git a/Minecraft.Client/LevelRenderer.cpp b/Minecraft.Client/LevelRenderer.cpp index cf2937f4fb..edcf67b894 100644 --- a/Minecraft.Client/LevelRenderer.cpp +++ b/Minecraft.Client/LevelRenderer.cpp @@ -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) ); } } diff --git a/Minecraft.Client/PreStitchedTextureMap.cpp b/Minecraft.Client/PreStitchedTextureMap.cpp index 33e0b59ecf..f8cc7f0e81 100644 --- a/Minecraft.Client/PreStitchedTextureMap.cpp +++ b/Minecraft.Client/PreStitchedTextureMap.cpp @@ -3,6 +3,7 @@ #include "..\Minecraft.World\net.minecraft.world.level.tile.h" #include "..\Minecraft.World\net.minecraft.world.item.h" #include "..\Minecraft.World\ByteBuffer.h" +#include "..\Minecraft.World\ArmorItem.h" #include "Minecraft.h" #include "LevelRenderer.h" #include "EntityRenderDispatcher.h" @@ -105,6 +106,8 @@ void PreStitchedTextureMap::stitch() } else #endif + texturePack->generateStitched(texturesByName); // add fallback so custom ones work? + if(texturePack->hasFile(L"res/" + filename,false)) { drive = texturePack->getPath(true); @@ -309,6 +312,8 @@ Icon *PreStitchedTextureMap::getMissingIcon() } #define ADD_ICON(row, column, name) (texturesByName[name] = new SimpleIcon(name,name,horizRatio*column,vertRatio*row,horizRatio*(column+1),vertRatio*(row+1))); +#define ADD_OBJ_ICON(row, column, tile) (texturesByName[tile->getIconName()] = new SimpleIcon(tile->getIconName(),tile->getIconName(),horizRatio*column,vertRatio*row,horizRatio*(column+1),vertRatio*(row+1))); +#define ADD_COL_TILE_ICON(row, column, tile, id) (texturesByName[((ColoredTile*)tile)->getColoredIconName(DyePowderItem::id)] = new SimpleIcon(((ColoredTile*)tile)->getColoredIconName(DyePowderItem::id),((ColoredTile*)tile)->getColoredIconName(DyePowderItem::id),horizRatio*column,vertRatio*row,horizRatio*(column+1),vertRatio*(row+1))); #define ADD_ICON_WITH_NAME(row, column, name, filename) (texturesByName[name] = new SimpleIcon(name,filename,horizRatio*column,vertRatio*row,horizRatio*(column+1),vertRatio*(row+1))); #define ADD_ICON_SIZE(row, column, name, height, width) (texturesByName[name] = new SimpleIcon(name,name,horizRatio*column,vertRatio*row,horizRatio*(column+width),vertRatio*(row+height))); @@ -333,227 +338,227 @@ void PreStitchedTextureMap::loadUVs() float horizRatio = 1.0f/16.0f; float vertRatio = 1.0f/16.0f; - ADD_ICON(0, 0, L"helmetCloth") - ADD_ICON(0, 1, L"helmetChain") - ADD_ICON(0, 2, L"helmetIron") - ADD_ICON(0, 3, L"helmetDiamond") - ADD_ICON(0, 4, L"helmetGold") - ADD_ICON(0, 5, L"flintAndSteel") - ADD_ICON(0, 6, L"flint") - ADD_ICON(0, 7, L"coal") - ADD_ICON(0, 8, L"string") - ADD_ICON(0, 9, L"seeds") - ADD_ICON(0, 10, L"apple") - ADD_ICON(0, 11, L"appleGold") - ADD_ICON(0, 12, L"egg") - ADD_ICON(0, 13, L"sugar") - ADD_ICON(0, 14, L"snowball") - ADD_ICON(0, 15, L"slot_empty_helmet") - - ADD_ICON(1, 0, L"chestplateCloth") - ADD_ICON(1, 1, L"chestplateChain") - ADD_ICON(1, 2, L"chestplateIron") - ADD_ICON(1, 3, L"chestplateDiamond") - ADD_ICON(1, 4, L"chestplateGold") - ADD_ICON(1, 5, L"bow") - ADD_ICON(1, 6, L"brick") - ADD_ICON(1, 7, L"ingotIron") + ADD_OBJ_ICON(0, 0, Item::helmet_leather) + ADD_OBJ_ICON(0, 1, Item::helmet_chain) + ADD_OBJ_ICON(0, 2, Item::helmet_iron) + ADD_OBJ_ICON(0, 3, Item::helmet_diamond) + ADD_OBJ_ICON(0, 4, Item::helmet_gold) + ADD_OBJ_ICON(0, 5, Item::flintAndSteel) + ADD_OBJ_ICON(0, 6, Item::flint) + ADD_OBJ_ICON(0, 7, Item::coal) + ADD_OBJ_ICON(0, 8, Item::string) + ADD_OBJ_ICON(0, 9, Item::seeds_wheat) + ADD_OBJ_ICON(0, 10, Item::apple) + ADD_OBJ_ICON(0, 11, Item::apple_gold) + ADD_OBJ_ICON(0, 12, Item::egg) + ADD_OBJ_ICON(0, 13, Item::sugar) + ADD_OBJ_ICON(0, 14, Item::snowBall) + ADD_ICON(0, 15, ((ArmorItem*)Item::boots_iron)->TEXTURE_EMPTY_SLOTS[0]) + + ADD_OBJ_ICON(1, 0, Item::chestplate_leather) + ADD_OBJ_ICON(1, 1, Item::chestplate_chain) + ADD_OBJ_ICON(1, 2, Item::chestplate_iron) + ADD_OBJ_ICON(1, 3, Item::chestplate_diamond) + ADD_OBJ_ICON(1, 4, Item::chestplate_gold) + ADD_OBJ_ICON(1, 5, Item::bow) + ADD_OBJ_ICON(1, 6, Item::brick) + ADD_OBJ_ICON(1, 7, Item::ironIngot) ADD_ICON(1, 8, L"feather") - ADD_ICON(1, 9, L"wheat") + ADD_OBJ_ICON(1, 9, Item::wheat) ADD_ICON(1, 10, L"painting") - ADD_ICON(1, 11, L"reeds") - ADD_ICON(1, 12, L"bone") - ADD_ICON(1, 13, L"cake") - ADD_ICON(1, 14, L"slimeball") - ADD_ICON(1, 15, L"slot_empty_chestplate") - - ADD_ICON(2, 0, L"leggingsCloth") - ADD_ICON(2, 1, L"leggingsChain") - ADD_ICON(2, 2, L"leggingsIron") - ADD_ICON(2, 3, L"leggingsDiamond") - ADD_ICON(2, 4, L"leggingsGold") - ADD_ICON(2, 5, L"arrow") + ADD_OBJ_ICON(1, 11, Item::reeds) + ADD_OBJ_ICON(1, 12, Item::bone) + ADD_OBJ_ICON(1, 13, Item::cake) + ADD_OBJ_ICON(1, 14, Item::slimeBall) + ADD_ICON(1, 15, ((ArmorItem*)Item::boots_iron)->TEXTURE_EMPTY_SLOTS[1]) // L"empty_armor_slot_chestplate") + + ADD_OBJ_ICON(2, 0, Item::leggings_leather) + ADD_OBJ_ICON(2, 1, Item::leggings_chain) + ADD_OBJ_ICON(2, 2, Item::leggings_iron) + ADD_OBJ_ICON(2, 3, Item::leggings_diamond) + ADD_OBJ_ICON(2, 4, Item::leggings_gold) + ADD_OBJ_ICON(2, 5, Item::arrow) ADD_ICON(2, 6, L"quiver") - ADD_ICON(2, 7, L"ingotGold") - ADD_ICON(2, 8, L"sulphur") - ADD_ICON(2, 9, L"bread") - ADD_ICON(2, 10, L"sign") - ADD_ICON(2, 11, L"doorWood") - ADD_ICON(2, 12, L"doorIron") - ADD_ICON(2, 13, L"bed") - ADD_ICON(2, 14, L"fireball") - ADD_ICON(2, 15, L"slot_empty_leggings") - - ADD_ICON(3, 0, L"bootsCloth") - ADD_ICON(3, 1, L"bootsChain") - ADD_ICON(3, 2, L"bootsIron") - ADD_ICON(3, 3, L"bootsDiamond") - ADD_ICON(3, 4, L"bootsGold") - ADD_ICON(3, 5, L"stick") + ADD_OBJ_ICON(2, 7, Item::goldIngot) + ADD_OBJ_ICON(2, 8, Item::gunpowder) + ADD_OBJ_ICON(2, 9, Item::bread) + ADD_OBJ_ICON(2, 10, Item::sign) + ADD_OBJ_ICON(2, 11, Item::door_wood) + ADD_OBJ_ICON(2, 12, Item::door_iron) + ADD_OBJ_ICON(2, 13, Item::bed) + ADD_OBJ_ICON(2, 14, Item::fireball) + ADD_ICON(2, 15, ((ArmorItem*)Item::boots_iron)->TEXTURE_EMPTY_SLOTS[2]) + + ADD_OBJ_ICON(3, 0, Item::boots_leather) + ADD_OBJ_ICON(3, 1, Item::boots_chain) + ADD_OBJ_ICON(3, 2, Item::boots_iron) + ADD_OBJ_ICON(3, 3, Item::boots_diamond) + ADD_OBJ_ICON(3, 4, Item::boots_gold) + ADD_OBJ_ICON(3, 5, Item::stick) ADD_ICON(3, 6, L"compass") - ADD_ICON(3, 7, L"diamond") - ADD_ICON(3, 8, L"redstone") - ADD_ICON(3, 9, L"clay") - ADD_ICON(3, 10, L"paper") - ADD_ICON(3, 11, L"book") - ADD_ICON(3, 12, L"map") - ADD_ICON(3, 13, L"seeds_pumpkin") - ADD_ICON(3, 14, L"seeds_melon") - ADD_ICON(3, 15, L"slot_empty_boots") - - ADD_ICON(4, 0, L"swordWood") - ADD_ICON(4, 1, L"swordStone") - ADD_ICON(4, 2, L"swordIron") - ADD_ICON(4, 3, L"swordDiamond") - ADD_ICON(4, 4, L"swordGold") - ADD_ICON(4, 5, L"fishingRod_uncast") + ADD_OBJ_ICON(3, 7, Item::diamond) + ADD_OBJ_ICON(3, 8, Item::redStone) + ADD_OBJ_ICON(3, 9, Item::clay) + ADD_OBJ_ICON(3, 10, Item::paper) + ADD_OBJ_ICON(3, 11, Item::book) + ADD_ICON(3, 12, L"filled_map") + ADD_OBJ_ICON(3, 13, Item::seeds_pumpkin) + ADD_OBJ_ICON(3, 14, Item::seeds_melon) + ADD_ICON(3, 15, ((ArmorItem*)Item::boots_iron)->TEXTURE_EMPTY_SLOTS[3]) + + ADD_OBJ_ICON(4, 0, Item::sword_wood) + ADD_OBJ_ICON(4, 1, Item::sword_stone) + ADD_OBJ_ICON(4, 2, Item::sword_iron) + ADD_OBJ_ICON(4, 3, Item::sword_diamond) + ADD_OBJ_ICON(4, 4, Item::sword_gold) + ADD_OBJ_ICON(4, 5, Item::fishingRod) ADD_ICON(4, 6, L"clock") - ADD_ICON(4, 7, L"bowl") - ADD_ICON(4, 8, L"mushroomStew") - ADD_ICON(4, 9, L"yellowDust") - ADD_ICON(4, 10, L"bucket") - ADD_ICON(4, 11, L"bucketWater") - ADD_ICON(4, 12, L"bucketLava") - ADD_ICON(4, 13, L"milk") - ADD_ICON(4, 14, L"dyePowder_black") - ADD_ICON(4, 15, L"dyePowder_gray") - - ADD_ICON(5, 0, L"shovelWood") - ADD_ICON(5, 1, L"shovelStone") - ADD_ICON(5, 2, L"shovelIron") - ADD_ICON(5, 3, L"shovelDiamond") - ADD_ICON(5, 4, L"shovelGold") - ADD_ICON(5, 5, L"fishingRod_cast") - ADD_ICON(5, 6, L"diode") - ADD_ICON(5, 7, L"porkchopRaw") - ADD_ICON(5, 8, L"porkchopCooked") - ADD_ICON(5, 9, L"fishRaw") - ADD_ICON(5, 10, L"fishCooked") - ADD_ICON(5, 11, L"rottenFlesh") - ADD_ICON(5, 12, L"cookie") - ADD_ICON(5, 13, L"shears") - ADD_ICON(5, 14, L"dyePowder_red") - ADD_ICON(5, 15, L"dyePowder_pink") - - ADD_ICON(6, 0, L"pickaxeWood") - ADD_ICON(6, 1, L"pickaxeStone") - ADD_ICON(6, 2, L"pickaxeIron") - ADD_ICON(6, 3, L"pickaxeDiamond") - ADD_ICON(6, 4, L"pickaxeGold") + ADD_OBJ_ICON(4, 7, Item::bowl) + ADD_OBJ_ICON(4, 8, Item::mushroomStew) + ADD_OBJ_ICON(4, 9, Item::yellowDust) + ADD_OBJ_ICON(4, 10, Item::bucket_empty) + ADD_OBJ_ICON(4, 11, Item::bucket_water) + ADD_OBJ_ICON(4, 12, Item::bucket_lava) + ADD_OBJ_ICON(4, 13, Item::bucket_milk) + ADD_ICON(4, 14, L"black_dye") + ADD_ICON(4, 15, L"gray_dye") + + ADD_OBJ_ICON(5, 0, Item::shovel_wood) + ADD_OBJ_ICON(5, 1, Item::shovel_stone) + ADD_OBJ_ICON(5, 2, Item::shovel_iron) + ADD_OBJ_ICON(5, 3, Item::shovel_diamond) + ADD_OBJ_ICON(5, 4, Item::shovel_gold) + ADD_ICON(5, 5, L"fishing_rod_cast") + ADD_OBJ_ICON(5, 6, Item::repeater) + ADD_OBJ_ICON(5, 7, Item::porkChop_raw) + ADD_OBJ_ICON(5, 8, Item::porkChop_cooked) + ADD_OBJ_ICON(5, 9, Item::fish_raw) + ADD_OBJ_ICON(5, 10, Item::fish_cooked) + ADD_OBJ_ICON(5, 11, Item::rotten_flesh) + ADD_OBJ_ICON(5, 12, Item::cookie) + ADD_OBJ_ICON(5, 13, Item::shears) + ADD_ICON(5, 14, L"red_dye") + ADD_ICON(5, 15, L"pink_dye") + + ADD_OBJ_ICON(6, 0, Item::pickAxe_wood) + ADD_OBJ_ICON(6, 1, Item::pickAxe_stone) + ADD_OBJ_ICON(6, 2, Item::pickAxe_iron) + ADD_OBJ_ICON(6, 3, Item::pickAxe_diamond) + ADD_OBJ_ICON(6, 4, Item::pickAxe_gold) ADD_ICON(6, 5, L"bow_pull_0") - ADD_ICON(6, 6, L"carrotOnAStick") - ADD_ICON(6, 7, L"leather") - ADD_ICON(6, 8, L"saddle") - ADD_ICON(6, 9, L"beefRaw") - ADD_ICON(6, 10, L"beefCooked") - ADD_ICON(6, 11, L"enderPearl") - ADD_ICON(6, 12, L"blazeRod") - ADD_ICON(6, 13, L"melon") - ADD_ICON(6, 14, L"dyePowder_green") - ADD_ICON(6, 15, L"dyePowder_lime") - - ADD_ICON(7, 0, L"hatchetWood") - ADD_ICON(7, 1, L"hatchetStone") - ADD_ICON(7, 2, L"hatchetIron") - ADD_ICON(7, 3, L"hatchetDiamond") - ADD_ICON(7, 4, L"hatchetGold") + ADD_OBJ_ICON(6, 6, Item::carrotOnAStick) + ADD_OBJ_ICON(6, 7, Item::leather) + ADD_OBJ_ICON(6, 8, Item::saddle) + ADD_OBJ_ICON(6, 9, Item::beef_raw) + ADD_OBJ_ICON(6, 10, Item::beef_cooked) + ADD_OBJ_ICON(6, 11, Item::enderPearl) + ADD_OBJ_ICON(6, 12, Item::blazeRod) + ADD_OBJ_ICON(6, 13, Item::melon) + ADD_ICON(6, 14, L"green_dye") + ADD_ICON(6, 15, L"lime_dye") + + ADD_OBJ_ICON(7, 0, Item::hatchet_wood) + ADD_OBJ_ICON(7, 1, Item::hatchet_stone) + ADD_OBJ_ICON(7, 2, Item::hatchet_iron) + ADD_OBJ_ICON(7, 3, Item::hatchet_diamond) + ADD_OBJ_ICON(7, 4, Item::hatchet_gold) ADD_ICON(7, 5, L"bow_pull_1") - ADD_ICON(7, 6, L"potatoBaked") - ADD_ICON(7, 7, L"potato") - ADD_ICON(7, 8, L"carrots") - ADD_ICON(7, 9, L"chickenRaw") - ADD_ICON(7, 10, L"chickenCooked") - ADD_ICON(7, 11, L"ghastTear") - ADD_ICON(7, 12, L"goldNugget") - ADD_ICON(7, 13, L"netherStalkSeeds") - ADD_ICON(7, 14, L"dyePowder_brown") - ADD_ICON(7, 15, L"dyePowder_yellow") - - ADD_ICON(8, 0, L"hoeWood") - ADD_ICON(8, 1, L"hoeStone") - ADD_ICON(8, 2, L"hoeIron") - ADD_ICON(8, 3, L"hoeDiamond") - ADD_ICON(8, 4, L"hoeGold") + ADD_OBJ_ICON(7, 6, Item::potatoBaked) + ADD_OBJ_ICON(7, 7, Item::potato) + ADD_OBJ_ICON(7, 8, Item::carrots) + ADD_OBJ_ICON(7, 9, Item::chicken_raw) + ADD_OBJ_ICON(7, 10, Item::chicken_cooked) + ADD_OBJ_ICON(7, 11, Item::ghastTear) + ADD_OBJ_ICON(7, 12, Item::goldNugget) + ADD_OBJ_ICON(7, 13, Item::netherwart_seeds) + ADD_ICON(7, 14, L"brown_dye") + ADD_ICON(7, 15, L"yellow_dye") + + ADD_OBJ_ICON(8, 0, Item::hoe_wood) + ADD_OBJ_ICON(8, 1, Item::hoe_stone) + ADD_OBJ_ICON(8, 2, Item::hoe_iron) + ADD_OBJ_ICON(8, 3, Item::hoe_diamond) + ADD_OBJ_ICON(8, 4, Item::hoe_gold) ADD_ICON(8, 5, L"bow_pull_2") - ADD_ICON(8, 6, L"potatoPoisonous") - ADD_ICON(8, 7, L"minecart") - ADD_ICON(8, 8, L"boat") - ADD_ICON(8, 9, L"speckledMelon") - ADD_ICON(8, 10, L"fermentedSpiderEye") - ADD_ICON(8, 11, L"spiderEye") - ADD_ICON(8, 12, L"potion") - ADD_ICON(8, 12, L"glassBottle") // Same as potion - ADD_ICON(8, 13, L"potion_contents") - ADD_ICON(8, 14, L"dyePowder_blue") - ADD_ICON(8, 15, L"dyePowder_light_blue") - - ADD_ICON(9, 0, L"helmetCloth_overlay") + ADD_OBJ_ICON(8, 6, Item::potatoPoisonous) + ADD_OBJ_ICON(8, 7, Item::minecart) + ADD_OBJ_ICON(8, 8, Item::boat) + ADD_OBJ_ICON(8, 9, Item::speckledMelon) + ADD_OBJ_ICON(8, 10, Item::fermentedSpiderEye) + ADD_OBJ_ICON(8, 11, Item::spiderEye) + ADD_OBJ_ICON(8, 12, Item::potion) + ADD_OBJ_ICON(8, 12, Item::glassBottle) // Same as potion + ADD_ICON(8, 13, ((PotionItem*)Item::potion)->CONTENTS_ICON) + ADD_ICON(8, 14, L"blue_dye") + ADD_ICON(8, 15, L"light_blue_dye") + + ADD_ICON(9, 0, ((ArmorItem*)Item::boots_iron)->LEATHER_OVERLAYS[0]) //ADD_ICON(9, 1, L"unused") - ADD_ICON(9, 2, L"iron_horse_armor") - ADD_ICON(9, 3, L"diamond_horse_armor") - ADD_ICON(9, 4, L"gold_horse_armor") - ADD_ICON(9, 5, L"comparator") - ADD_ICON(9, 6, L"carrotGolden") - ADD_ICON(9, 7, L"minecart_chest") - ADD_ICON(9, 8, L"pumpkinPie") - ADD_ICON(9, 9, L"monsterPlacer") - ADD_ICON(9, 10, L"potion_splash") - ADD_ICON(9, 11, L"eyeOfEnder") - ADD_ICON(9, 12, L"cauldron") - ADD_ICON(9, 13, L"blazePowder") - ADD_ICON(9, 14, L"dyePowder_purple") - ADD_ICON(9, 15, L"dyePowder_magenta") - - ADD_ICON(10, 0, L"chestplateCloth_overlay") + ADD_OBJ_ICON(9, 2, Item::horseArmorMetal) + ADD_OBJ_ICON(9, 3, Item::horseArmorDiamond) + ADD_OBJ_ICON(9, 4, Item::horseArmorGold) + ADD_OBJ_ICON(9, 5, Item::comparator) + ADD_OBJ_ICON(9, 6, Item::carrotGolden) + ADD_OBJ_ICON(9, 7, Item::minecart_chest) + ADD_OBJ_ICON(9, 8, Item::pumpkinPie) + ADD_OBJ_ICON(9, 9, Item::spawnEgg) + ADD_ICON(9, 10, ((PotionItem*)Item::potion)->THROWABLE_ICON) + ADD_OBJ_ICON(9, 11, Item::eyeOfEnder) + ADD_OBJ_ICON(9, 12, Item::cauldron) + ADD_OBJ_ICON(9, 13, Item::blazePowder) + ADD_ICON(9, 14, L"purple_dye") + ADD_ICON(9, 15, L"magenta_dye") + + ADD_ICON(10, 0, ((ArmorItem*)Item::boots_iron)->LEATHER_OVERLAYS[1]) //ADD_ICON(10, 1, L"unused") //ADD_ICON(10, 2, L"unused") - ADD_ICON(10, 3, L"name_tag") - ADD_ICON(10, 4, L"lead") - ADD_ICON(10, 5, L"netherbrick") + ADD_OBJ_ICON(10, 3, Item::nameTag) + ADD_OBJ_ICON(10, 4, Item::lead) + ADD_OBJ_ICON(10, 5, Item::netherbrick) //ADD_ICON(10, 6, L"unused") - ADD_ICON(10, 7, L"minecart_furnace") + ADD_OBJ_ICON(10, 7, Item::minecart_furnace) ADD_ICON(10, 8, L"charcoal") - ADD_ICON(10, 9, L"monsterPlacer_overlay") + ADD_ICON(10, 9, L"spawn_egg_overlay") ADD_ICON(10, 10, L"ruby") - ADD_ICON(10, 11, L"expBottle") - ADD_ICON(10, 12, L"brewingStand") - ADD_ICON(10, 13, L"magmaCream") - ADD_ICON(10, 14, L"dyePowder_cyan") - ADD_ICON(10, 15, L"dyePowder_orange") + ADD_OBJ_ICON(10, 11, Item::expBottle) + ADD_OBJ_ICON(10, 12, Item::brewingStand) + ADD_OBJ_ICON(10, 13, Item::magmaCream) + ADD_ICON(10, 14, L"cyan_dye") + ADD_ICON(10, 15, L"orange_dye") - ADD_ICON(11, 0, L"leggingsCloth_overlay") + ADD_ICON(11, 0, ((ArmorItem*)Item::boots_iron)->LEATHER_OVERLAYS[2]) //ADD_ICON(11, 1, L"unused") //ADD_ICON(11, 2, L"unused") //ADD_ICON(11, 3, L"unused") //ADD_ICON(11, 4, L"unused") //ADD_ICON(11, 5, L"unused") //ADD_ICON(11, 6, L"unused") - ADD_ICON(11, 7, L"minecart_hopper") - ADD_ICON(11, 8, L"hopper") - ADD_ICON(11, 9, L"nether_star") - ADD_ICON(11, 10, L"emerald") - ADD_ICON(11, 11, L"writingBook") - ADD_ICON(11, 12, L"writtenBook") - ADD_ICON(11, 13, L"flowerPot") - ADD_ICON(11, 14, L"dyePowder_silver") - ADD_ICON(11, 15, L"dyePowder_white") - - ADD_ICON(12, 0, L"bootsCloth_overlay") + ADD_OBJ_ICON(11, 7, Item::minecart_hopper) + ADD_ICON(11, 8, L"hopper") + ADD_OBJ_ICON(11, 9, Item::netherStar) + ADD_OBJ_ICON(11, 10, Item::emerald) + ADD_ICON(11, 11, L"writable_book") + ADD_ICON(11, 12, L"written_book") + ADD_OBJ_ICON(11, 13, Item::flowerPot) + ADD_ICON(11, 14, L"light_gray_dye") + ADD_ICON(11, 15, L"white_dye") + + ADD_ICON(12, 0, ((ArmorItem*)Item::boots_iron)->LEATHER_OVERLAYS[3]) //ADD_ICON(12, 1, L"unused") //ADD_ICON(12, 2, L"unused") //ADD_ICON(12, 3, L"unused") //ADD_ICON(12, 4, L"unused") //ADD_ICON(12, 5, L"unused") //ADD_ICON(12, 6, L"unused") - ADD_ICON(12, 7, L"minecart_tnt") + ADD_OBJ_ICON(12, 7, Item::minecart_tnt) //ADD_ICON(12, 8, L"unused") - ADD_ICON(12, 9, L"fireworks") - ADD_ICON(12, 10, L"fireworks_charge") + ADD_OBJ_ICON(12, 9, Item::fireworks) + ADD_OBJ_ICON(12, 10, Item::fireworksCharge) ADD_ICON(12, 11, L"fireworks_charge_overlay") - ADD_ICON(12, 12, L"netherquartz") - ADD_ICON(12, 13, L"map_empty") - ADD_ICON(12, 14, L"frame") - ADD_ICON(12, 15, L"enchantedBook") + ADD_OBJ_ICON(12, 12, Item::netherQuartz) + ADD_ICON(12, 13, L"map") + ADD_OBJ_ICON(12, 14, Item::frame) + ADD_OBJ_ICON(12, 15, Item::enchantedBook) ADD_ICON(14, 0, L"skull_skeleton") ADD_ICON(14, 1, L"skull_wither") @@ -572,18 +577,18 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON_WITH_NAME(14, 14, L"clockP3", L"clock") // 4J Added ADD_ICON(14, 15, L"dragonFireball") - ADD_ICON(15, 0, L"record_13") - ADD_ICON(15, 1, L"record_cat") - ADD_ICON(15, 2, L"record_blocks") - ADD_ICON(15, 3, L"record_chirp") - ADD_ICON(15, 4, L"record_far") - ADD_ICON(15, 5, L"record_mall") - ADD_ICON(15, 6, L"record_mellohi") - ADD_ICON(15, 7, L"record_stal") - ADD_ICON(15, 8, L"record_strad") - ADD_ICON(15, 9, L"record_ward") - ADD_ICON(15, 10, L"record_11") - ADD_ICON(15, 11, L"record_where are we now") + ADD_ICON(15, 0, L"music_disc_13") + ADD_ICON(15, 1, L"music_disc_cat") + ADD_ICON(15, 2, L"music_disc_blocks") + ADD_ICON(15, 3, L"music_disc_chirp") + ADD_ICON(15, 4, L"music_disc_far") + ADD_ICON(15, 5, L"music_disc_mall") + ADD_ICON(15, 6, L"music_disc_mellohi") + ADD_ICON(15, 7, L"music_disc_stal") + ADD_ICON(15, 8, L"music_disc_strad") + ADD_ICON(15, 9, L"music_disc_ward") + ADD_ICON(15, 10, L"music_disc_11") + ADD_ICON(15, 11, L"music_disc_where are we now") // Special cases ClockTexture *dataClock = new ClockTexture(); @@ -651,54 +656,54 @@ void PreStitchedTextureMap::loadUVs() float horizRatio = 1.0f/16.0f; float vertRatio = 1.0f/32.0f; - ADD_ICON(0, 0, L"grass_top") - texturesByName[L"grass_top"]->setFlags(Icon::IS_GRASS_TOP); // 4J added for faster determination of texture type in tesselation + ADD_ICON(0, 0, L"grass_block_top") + texturesByName[L"grass_block_top"]->setFlags(Icon::IS_GRASS_TOP); // 4J added for faster determination of texture type in tesselation ADD_ICON(0, 1, L"stone") ADD_ICON(0, 2, L"dirt") - ADD_ICON(0, 3, L"grass_side") - texturesByName[L"grass_side"]->setFlags(Icon::IS_GRASS_SIDE); // 4J added for faster determination of texture type in tesselation - ADD_ICON(0, 4, L"planks_oak") - ADD_ICON(0, 5, L"stoneslab_side") - ADD_ICON(0, 6, L"stoneslab_top") - ADD_ICON(0, 7, L"brick") + ADD_ICON(0, 3, L"grass_block_side") + texturesByName[L"grass_block_side"]->setFlags(Icon::IS_GRASS_SIDE); // 4J added for faster determination of texture type in tesselation + ADD_ICON(0, 4, L"oak_planks") + ADD_ICON(0, 5, L"smooth_stone_slab_side") + ADD_ICON(0, 6, L"smooth_stone") + ADD_OBJ_ICON(0, 7, Tile::redBrick) ADD_ICON(0, 8, L"tnt_side") ADD_ICON(0, 9, L"tnt_top") ADD_ICON(0, 10, L"tnt_bottom") - ADD_ICON(0, 11, L"web") - ADD_ICON(0, 12, L"flower_rose") - ADD_ICON(0, 13, L"flower_dandelion") + ADD_OBJ_ICON(0, 11, Tile::web) + ADD_OBJ_ICON(0, 12, Tile::rose) + ADD_OBJ_ICON(0, 13, Tile::flower) ADD_ICON(0, 14, L"portal") - ADD_ICON(0, 15, L"sapling") + ADD_ICON(0, 15, L"oak_sapling") ADD_ICON(1, 0, L"cobblestone"); ADD_ICON(1, 1, L"bedrock"); ADD_ICON(1, 2, L"sand"); ADD_ICON(1, 3, L"gravel"); - ADD_ICON(1, 4, L"log_oak"); - ADD_ICON(1, 5, L"log_oak_top"); + ADD_ICON(1, 4, L"oak_log"); + ADD_ICON(1, 5, L"oak_log_top"); ADD_ICON(1, 6, L"iron_block"); ADD_ICON(1, 7, L"gold_block"); ADD_ICON(1, 8, L"diamond_block"); ADD_ICON(1, 9, L"emerald_block"); ADD_ICON(1, 10, L"redstone_block"); - ADD_ICON(1, 11, L"dropper_front_horizontal"); - ADD_ICON(1, 12, L"mushroom_red"); - ADD_ICON(1, 13, L"mushroom_brown"); - ADD_ICON(1, 14, L"sapling_jungle"); + ADD_ICON(1, 11, L"dropper_front"); + ADD_OBJ_ICON(1, 12, Tile::mushroom_red); + ADD_OBJ_ICON(1, 13, Tile::mushroom_brown); + ADD_ICON(1, 14, L"jungle_sapling"); ADD_ICON(1, 15, L"fire_0"); ADD_ICON(2, 0, L"gold_ore"); ADD_ICON(2, 1, L"iron_ore"); ADD_ICON(2, 2, L"coal_ore"); ADD_ICON(2, 3, L"bookshelf"); - ADD_ICON(2, 4, L"cobblestone_mossy"); - ADD_ICON(2, 5, L"obsidian"); - ADD_ICON(2, 6, L"grass_side_overlay"); - ADD_ICON(2, 7, L"tallgrass"); + ADD_OBJ_ICON(2, 4, Tile::mossyCobblestone); + ADD_OBJ_ICON(2, 5, Tile::obsidian); + ADD_ICON(2, 6, L"grass_block_side_overlay"); + ADD_OBJ_ICON(2, 7, Tile::tallgrass); ADD_ICON(2, 8, L"dispenser_front_vertical"); ADD_ICON(2, 9, L"beacon"); ADD_ICON(2, 10, L"dropper_front_vertical"); - ADD_ICON(2, 11, L"workbench_top"); + ADD_ICON(2, 11, L"crafting_table_top"); ADD_ICON(2, 12, L"furnace_front"); ADD_ICON(2, 13, L"furnace_side"); ADD_ICON(2, 14, L"dispenser_front"); @@ -706,95 +711,95 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(3, 0, L"sponge"); ADD_ICON(3, 1, L"glass"); - ADD_ICON(3, 2, L"diamond_ore"); - ADD_ICON(3, 3, L"redstone_ore"); - ADD_ICON(3, 4, L"leaves"); - ADD_ICON(3, 5, L"leaves_opaque"); - ADD_ICON(3, 6, L"stonebrick"); - ADD_ICON(3, 7, L"deadbush"); + ADD_OBJ_ICON(3, 2, Tile::diamondOre); + ADD_OBJ_ICON(3, 3, Tile::redStoneOre); + ADD_ICON(3, 4, L"oak_leaves"); + ADD_ICON(3, 5, L"oak_leaves_opaque"); + ADD_OBJ_ICON(3, 6, Tile::stoneBrick); + ADD_OBJ_ICON(3, 7, Tile::deadBush); ADD_ICON(3, 8, L"fern"); ADD_ICON(3, 9, L"daylight_detector_top"); ADD_ICON(3, 10, L"daylight_detector_side"); - ADD_ICON(3, 11, L"workbench_side"); - ADD_ICON(3, 12, L"workbench_front"); - ADD_ICON(3, 13, L"furnace_front_lit"); + ADD_ICON(3, 11, L"crafting_table_side"); + ADD_ICON(3, 12, L"crafting_table_front"); + ADD_ICON(3, 13, L"furnace_front_on"); ADD_ICON(3, 14, L"furnace_top"); - ADD_ICON(3, 15, L"sapling_spruce"); + ADD_ICON(3, 15, L"spruce_sapling"); - ADD_ICON(4, 0, L"wool_colored_white"); - ADD_ICON(4, 1, L"mob_spawner"); + ADD_COL_TILE_ICON(4, 0, Tile::wool, WHITE); + ADD_OBJ_ICON(4, 1, Tile::mobSpawner); ADD_ICON(4, 2, L"snow"); ADD_ICON(4, 3, L"ice"); - ADD_ICON(4, 4, L"snow_side"); + ADD_ICON(4, 4, L"grass_block_snow"); ADD_ICON(4, 5, L"cactus_top"); ADD_ICON(4, 6, L"cactus_side"); ADD_ICON(4, 7, L"cactus_bottom"); ADD_ICON(4, 8, L"clay"); - ADD_ICON(4, 9, L"reeds"); + ADD_OBJ_ICON(4, 9, Tile::reeds); ADD_ICON(4, 10, L"jukebox_side"); ADD_ICON(4, 11, L"jukebox_top"); - ADD_ICON(4, 12, L"waterlily"); - ADD_ICON(4, 13, L"mycel_side"); - ADD_ICON(4, 14, L"mycel_top"); - ADD_ICON(4, 15, L"sapling_birch"); - - ADD_ICON(5, 0, L"torch_on"); - ADD_ICON(5, 1, L"door_wood_upper"); - ADD_ICON(5, 2, L"door_iron_upper"); - ADD_ICON(5, 3, L"ladder"); - ADD_ICON(5, 4, L"trapdoor"); + ADD_OBJ_ICON(4, 12, Tile::waterLily); + ADD_ICON(4, 13, L"mycelium_side"); + ADD_ICON(4, 14, L"mycelium_top"); + ADD_ICON(4, 15, L"birch_sapling"); + + ADD_OBJ_ICON(5, 0, Tile::torch); + ADD_ICON(5, 1, L"oak_door_top"); + ADD_ICON(5, 2, L"iron_door_top"); + ADD_OBJ_ICON(5, 3, Tile::ladder); + ADD_OBJ_ICON(5, 4, Tile::trapdoor); ADD_ICON(5, 5, L"iron_bars"); - ADD_ICON(5, 6, L"farmland_wet"); - ADD_ICON(5, 7, L"farmland_dry"); - ADD_ICON(5, 8, L"crops_0"); - ADD_ICON(5, 9, L"crops_1"); - ADD_ICON(5, 10, L"crops_2"); - ADD_ICON(5, 11, L"crops_3"); - ADD_ICON(5, 12, L"crops_4"); - ADD_ICON(5, 13, L"crops_5"); - ADD_ICON(5, 14, L"crops_6"); - ADD_ICON(5, 15, L"crops_7"); + ADD_ICON(5, 6, L"farmland_moist"); + ADD_ICON(5, 7, L"farmland"); + ADD_ICON(5, 8, L"wheat_stage0"); + ADD_ICON(5, 9, L"wheat_stage1"); + ADD_ICON(5, 10, L"wheat_stage2"); + ADD_ICON(5, 11, L"wheat_stage3"); + ADD_ICON(5, 12, L"wheat_stage4"); + ADD_ICON(5, 13, L"wheat_stage5"); + ADD_ICON(5, 14, L"wheat_stage6"); + ADD_ICON(5, 15, L"wheat_stage7"); ADD_ICON(6, 0, L"lever"); - ADD_ICON(6, 1, L"door_wood_lower"); - ADD_ICON(6, 2, L"door_iron_lower"); - ADD_ICON(6, 3, L"redstone_torch_on"); - ADD_ICON(6, 4, L"stonebrick_mossy"); - ADD_ICON(6, 5, L"stonebrick_cracked"); + ADD_ICON(6, 1, L"oak_door_bottom"); + ADD_ICON(6, 2, L"iron_door_bottom"); + ADD_OBJ_ICON(6, 3, Tile::redstoneTorch_on); + ADD_ICON(6, 4, L"mossy_stone_bricks"); + ADD_ICON(6, 5, L"cracked_stone_bricks"); ADD_ICON(6, 6, L"pumpkin_top"); - ADD_ICON(6, 7, L"netherrack"); + ADD_OBJ_ICON(6, 7, Tile::netherRack); ADD_ICON(6, 8, L"soul_sand"); ADD_ICON(6, 9, L"glowstone"); ADD_ICON(6, 10, L"piston_top_sticky"); ADD_ICON(6, 11, L"piston_top"); ADD_ICON(6, 12, L"piston_side"); ADD_ICON(6, 13, L"piston_bottom"); - ADD_ICON(6, 14, L"piston_inner_top"); - ADD_ICON(6, 15, L"stem_straight"); - - ADD_ICON(7, 0, L"rail_normal_turned"); - ADD_ICON(7, 1, L"wool_colored_black"); - ADD_ICON(7, 2, L"wool_colored_gray"); - ADD_ICON(7, 3, L"redstone_torch_off"); - ADD_ICON(7, 4, L"log_spruce"); - ADD_ICON(7, 5, L"log_birch"); + ADD_ICON(6, 14, L"piston_inner"); + ADD_ICON(6, 15, L"pumpkin_stem_disconnected"); + + ADD_ICON(7, 0, L"rail_corner"); + ADD_COL_TILE_ICON(7, 1, Tile::wool, BLACK); + ADD_COL_TILE_ICON(7, 2, Tile::wool, GRAY); + ADD_OBJ_ICON(7, 3, Tile::redstoneTorch_off); + ADD_ICON(7, 4, L"spruce_log"); + ADD_ICON(7, 5, L"birch_log"); ADD_ICON(7, 6, L"pumpkin_side"); - ADD_ICON(7, 7, L"pumpkin_face_off"); - ADD_ICON(7, 8, L"pumpkin_face_on"); + ADD_ICON(7, 7, L"carved_pumpkin"); + ADD_ICON(7, 8, L"jack_o_lantern"); ADD_ICON(7, 9, L"cake_top"); ADD_ICON(7, 10, L"cake_side"); ADD_ICON(7, 11, L"cake_inner"); ADD_ICON(7, 12, L"cake_bottom"); - ADD_ICON(7, 13, L"mushroom_block_skin_red"); - ADD_ICON(7, 14, L"mushroom_block_skin_brown"); - ADD_ICON(7, 15, L"stem_bent"); - - ADD_ICON(8, 0, L"rail_normal"); - ADD_ICON(8, 1, L"wool_colored_red"); - ADD_ICON(8, 2, L"wool_colored_pink"); - ADD_ICON(8, 3, L"repeater_off"); - ADD_ICON(8, 4, L"leaves_spruce"); - ADD_ICON(8, 5, L"leaves_spruce_opaque"); + ADD_ICON(7, 13, L"red_mushroom_block"); + ADD_ICON(7, 14, L"brown_mushroom_block"); + ADD_ICON(7, 15, L"attached_pumpkin_stem"); + + ADD_ICON(8, 0, L"rail"); + ADD_COL_TILE_ICON(8, 1, Tile::wool, RED); + ADD_COL_TILE_ICON(8, 2, Tile::wool, PINK); + ADD_OBJ_ICON(8, 3, Tile::diode_off); + ADD_ICON(8, 4, L"spruce_leaves"); + ADD_ICON(8, 5, L"spruce_leaves_opaque"); ADD_ICON(8, 6, L"bed_feet_top"); ADD_ICON(8, 7, L"bed_head_top"); ADD_ICON(8, 8, L"melon_side"); @@ -802,189 +807,189 @@ void PreStitchedTextureMap::loadUVs() ADD_ICON(8, 10, L"cauldron_top"); ADD_ICON(8, 11, L"cauldron_inner"); //ADD_ICON(8, 12, L"unused"); - ADD_ICON(8, 13, L"mushroom_block_skin_stem"); + ADD_ICON(8, 13, L"mushroom_stem"); ADD_ICON(8, 14, L"mushroom_block_inside"); ADD_ICON(8, 15, L"vine"); ADD_ICON(9, 0, L"lapis_block"); - ADD_ICON(9, 1, L"wool_colored_green"); - ADD_ICON(9, 2, L"wool_colored_lime"); - ADD_ICON(9, 3, L"repeater_on"); + ADD_COL_TILE_ICON(9, 1, Tile::wool, GREEN); + ADD_COL_TILE_ICON(9, 2, Tile::wool, LIME); + ADD_OBJ_ICON(9, 3, Tile::diode_on); ADD_ICON(9, 4, L"glass_pane_top"); ADD_ICON(9, 5, L"bed_feet_end"); ADD_ICON(9, 6, L"bed_feet_side"); ADD_ICON(9, 7, L"bed_head_side"); ADD_ICON(9, 8, L"bed_head_end"); - ADD_ICON(9, 9, L"log_jungle"); + ADD_ICON(9, 9, L"jungle_log"); ADD_ICON(9, 10, L"cauldron_side"); ADD_ICON(9, 11, L"cauldron_bottom"); ADD_ICON(9, 12, L"brewing_stand_base"); ADD_ICON(9, 13, L"brewing_stand"); - ADD_ICON(9, 14, L"endframe_top"); - ADD_ICON(9, 15, L"endframe_side"); + ADD_ICON(9, 14, L"end_portal_frame_top"); + ADD_ICON(9, 15, L"end_portal_frame_side"); ADD_ICON(10, 0, L"lapis_ore"); - ADD_ICON(10, 1, L"wool_colored_brown"); - ADD_ICON(10, 2, L"wool_colored_yellow"); - ADD_ICON(10, 3, L"rail_golden"); + ADD_COL_TILE_ICON(10, 1, Tile::wool, BROWN); + ADD_COL_TILE_ICON(10, 2, Tile::wool, YELLOW); + ADD_OBJ_ICON(10, 3, Tile::goldenRail); ADD_ICON(10, 4, L"redstone_dust_cross"); ADD_ICON(10, 5, L"redstone_dust_line"); - ADD_ICON(10, 6, L"enchantment_top"); + ADD_ICON(10, 6, L"enchanting_table_top"); ADD_ICON(10, 7, L"dragon_egg"); - ADD_ICON(10, 8, L"cocoa_2"); - ADD_ICON(10, 9, L"cocoa_1"); - ADD_ICON(10, 10, L"cocoa_0"); + ADD_ICON(10, 8, L"cocoa_stage2"); + ADD_ICON(10, 9, L"cocoa_stage1"); + ADD_ICON(10, 10, L"cocoa_stage0"); ADD_ICON(10, 11, L"emerald_ore"); - ADD_ICON(10, 12, L"trip_wire_source"); - ADD_ICON(10, 13, L"trip_wire"); - ADD_ICON(10, 14, L"endframe_eye"); + ADD_OBJ_ICON(10, 12, Tile::tripWireSource); + ADD_OBJ_ICON(10, 13, Tile::tripWire); + ADD_ICON(10, 14, L"end_portal_frame_eye"); ADD_ICON(10, 15, L"end_stone"); ADD_ICON(11, 0, L"sandstone_top"); - ADD_ICON(11, 1, L"wool_colored_blue"); - ADD_ICON(11, 2, L"wool_colored_light_blue"); - ADD_ICON(11, 3, L"rail_golden_powered"); + ADD_COL_TILE_ICON(11, 1, Tile::wool, BLUE); + ADD_COL_TILE_ICON(11, 2, Tile::wool, LIGHT_BLUE); + ADD_ICON(11, 3, L"powered_rail_on"); ADD_ICON(11, 4, L"redstone_dust_cross_overlay"); ADD_ICON(11, 5, L"redstone_dust_line_overlay"); - ADD_ICON(11, 6, L"enchantment_side"); - ADD_ICON(11, 7, L"enchantment_bottom"); + ADD_ICON(11, 6, L"enchanting_table_side"); + ADD_ICON(11, 7, L"enchanting_table_bottom"); ADD_ICON(11, 8, L"command_block"); ADD_ICON(11, 9, L"itemframe_back"); ADD_ICON(11, 10, L"flower_pot"); - ADD_ICON(11, 11, L"comparator_off"); + ADD_ICON(11, 11, L"comparator"); ADD_ICON(11, 12, L"comparator_on"); - ADD_ICON(11, 13, L"rail_activator"); - ADD_ICON(11, 14, L"rail_activator_powered"); - ADD_ICON(11, 15, L"quartz_ore"); - - ADD_ICON(12, 0, L"sandstone_side"); - ADD_ICON(12, 1, L"wool_colored_purple"); - ADD_ICON(12, 2, L"wool_colored_magenta"); - ADD_ICON(12, 3, L"detectorRail"); - ADD_ICON(12, 4, L"leaves_jungle"); - ADD_ICON(12, 5, L"leaves_jungle_opaque"); - ADD_ICON(12, 6, L"planks_spruce"); - ADD_ICON(12, 7, L"planks_jungle"); - ADD_ICON(12, 8, L"carrots_stage_0"); - ADD_ICON(12, 9, L"carrots_stage_1"); - ADD_ICON(12, 10, L"carrots_stage_2"); - ADD_ICON(12, 11, L"carrots_stage_3"); + ADD_OBJ_ICON(11, 13, Tile::activatorRail); + ADD_ICON(11, 14, L"activator_rail_on"); + ADD_OBJ_ICON(11, 15, Tile::netherQuartz); + + ADD_ICON(12, 0, L"sandstone"); + ADD_COL_TILE_ICON(12, 1, Tile::wool, PURPLE); + ADD_COL_TILE_ICON(12, 2, Tile::wool, MAGENTA); + ADD_OBJ_ICON(12, 3, Tile::detectorRail); + ADD_ICON(12, 4, L"jungle_leaves"); + ADD_ICON(12, 5, L"jungle_leaves_opaque"); + ADD_ICON(12, 6, L"spruce_planks"); + ADD_ICON(12, 7, L"jungle_planks"); + ADD_ICON(12, 8, L"carrots_stage0"); + ADD_ICON(12, 9, L"carrots_stage1"); + ADD_ICON(12, 10, L"carrots_stage2"); + ADD_ICON(12, 11, L"carrots_stage3"); //ADD_ICON(12, 12, L"unused"); ADD_ICON(12, 13, L"water"); ADD_ICON_SIZE(12,14,L"water_flow",2,2); ADD_ICON(13, 0, L"sandstone_bottom"); - ADD_ICON(13, 1, L"wool_colored_cyan"); - ADD_ICON(13, 2, L"wool_colored_orange"); - ADD_ICON(13, 3, L"redstoneLight"); - ADD_ICON(13, 4, L"redstoneLight_lit"); - ADD_ICON(13, 5, L"stonebrick_carved"); - ADD_ICON(13, 6, L"planks_birch"); - ADD_ICON(13, 7, L"anvil_base"); - ADD_ICON(13, 8, L"anvil_top_damaged_1"); - ADD_ICON(13, 9, L"quartz_block_chiseled_top"); - ADD_ICON(13, 10, L"quartz_block_lines_top"); + ADD_COL_TILE_ICON(13, 1, Tile::wool, CYAN); + ADD_COL_TILE_ICON(13, 2, Tile::wool, ORANGE); + ADD_OBJ_ICON(13, 3, Tile::redstoneLight); + ADD_OBJ_ICON(13, 4, Tile::redstoneLight_lit); + ADD_ICON(13, 5, L"chiseled_stone_bricks"); + ADD_ICON(13, 6, L"birch_planks"); + ADD_ICON(13, 7, L"anvil"); + ADD_ICON(13, 8, L"chipped_anvil_top"); + ADD_ICON(13, 9, L"chiseled_quartz_block_top"); + ADD_ICON(13, 10, L"quartz_pillar_top"); ADD_ICON(13, 11, L"quartz_block_top"); ADD_ICON(13, 12, L"hopper_outside"); - ADD_ICON(13, 13, L"detectorRail_on"); - - ADD_ICON(14, 0, L"nether_brick"); - ADD_ICON(14, 1, L"wool_colored_silver"); - ADD_ICON(14, 2, L"nether_wart_stage_0"); - ADD_ICON(14, 3, L"nether_wart_stage_1"); - ADD_ICON(14, 4, L"nether_wart_stage_2"); - ADD_ICON(14, 5, L"sandstone_carved"); - ADD_ICON(14, 6, L"sandstone_smooth"); + ADD_ICON(13, 13, L"detector_rail_on"); + + ADD_OBJ_ICON(14, 0, Tile::netherBrick); + ADD_COL_TILE_ICON(14, 1, Tile::wool, SILVER); // light gray + ADD_ICON(14, 2, L"nether_wart_stage0"); + ADD_ICON(14, 3, L"nether_wart_stage1"); + ADD_ICON(14, 4, L"nether_wart_stage2"); + ADD_ICON(14, 5, L"chiseled_sandstone"); + ADD_ICON(14, 6, L"cut_sandstone"); ADD_ICON(14, 7, L"anvil_top"); - ADD_ICON(14, 8, L"anvil_top_damaged_2"); - ADD_ICON(14, 9, L"quartz_block_chiseled"); - ADD_ICON(14, 10, L"quartz_block_lines"); + ADD_ICON(14, 8, L"damaged_anvil_top"); + ADD_ICON(14, 9, L"chiseled_quartz_block"); + ADD_ICON(14, 10, L"quartz_pillar"); ADD_ICON(14, 11, L"quartz_block_side"); ADD_ICON(14, 12, L"hopper_inside"); ADD_ICON(14, 13, L"lava"); ADD_ICON_SIZE(14,14,L"lava_flow",2,2); - ADD_ICON(15, 0, L"destroy_0"); - ADD_ICON(15, 1, L"destroy_1"); - ADD_ICON(15, 2, L"destroy_2"); - ADD_ICON(15, 3, L"destroy_3"); - ADD_ICON(15, 4, L"destroy_4"); - ADD_ICON(15, 5, L"destroy_5"); - ADD_ICON(15, 6, L"destroy_6"); - ADD_ICON(15, 7, L"destroy_7"); - ADD_ICON(15, 8, L"destroy_8"); - ADD_ICON(15, 9, L"destroy_9"); + ADD_ICON(15, 0, L"destroy_stage_0"); + ADD_ICON(15, 1, L"destroy_stage_1"); + ADD_ICON(15, 2, L"destroy_stage_2"); + ADD_ICON(15, 3, L"destroy_stage_3"); + ADD_ICON(15, 4, L"destroy_stage_4"); + ADD_ICON(15, 5, L"destroy_stage_5"); + ADD_ICON(15, 6, L"destroy_stage_6"); + ADD_ICON(15, 7, L"destroy_stage_7"); + ADD_ICON(15, 8, L"destroy_stage_8"); + ADD_ICON(15, 9, L"destroy_stage_9"); ADD_ICON(15, 10, L"hay_block_side"); ADD_ICON(15, 11, L"quartz_block_bottom"); ADD_ICON(15, 12, L"hopper_top"); ADD_ICON(15, 13, L"hay_block_top"); ADD_ICON(16, 0, L"coal_block"); - ADD_ICON(16, 1, L"hardened_clay"); - ADD_ICON(16, 2, L"noteblock"); + ADD_OBJ_ICON(16, 1, Tile::clayHardened); + ADD_OBJ_ICON(16, 2, Tile::noteblock); //ADD_ICON(16, 3, L"unused"); //ADD_ICON(16, 4, L"unused"); //ADD_ICON(16, 5, L"unused"); //ADD_ICON(16, 6, L"unused"); //ADD_ICON(16, 7, L"unused"); //ADD_ICON(16, 8, L"unused"); - ADD_ICON(16, 9, L"potatoes_stage_0"); - ADD_ICON(16, 10, L"potatoes_stage_1"); - ADD_ICON(16, 11, L"potatoes_stage_2"); - ADD_ICON(16, 12, L"potatoes_stage_3"); - ADD_ICON(16, 13, L"log_spruce_top"); - ADD_ICON(16, 14, L"log_jungle_top"); - ADD_ICON(16, 15, L"log_birch_top"); - - ADD_ICON(17, 0, L"hardened_clay_stained_black"); - ADD_ICON(17, 1, L"hardened_clay_stained_blue"); - ADD_ICON(17, 2, L"hardened_clay_stained_brown"); - ADD_ICON(17, 3, L"hardened_clay_stained_cyan"); - ADD_ICON(17, 4, L"hardened_clay_stained_gray"); - ADD_ICON(17, 5, L"hardened_clay_stained_green"); - ADD_ICON(17, 6, L"hardened_clay_stained_light_blue"); - ADD_ICON(17, 7, L"hardened_clay_stained_lime"); - ADD_ICON(17, 8, L"hardened_clay_stained_magenta"); - ADD_ICON(17, 9, L"hardened_clay_stained_orange"); - ADD_ICON(17, 10, L"hardened_clay_stained_pink"); - ADD_ICON(17, 11, L"hardened_clay_stained_purple"); - ADD_ICON(17, 12, L"hardened_clay_stained_red"); - ADD_ICON(17, 13, L"hardened_clay_stained_silver"); - ADD_ICON(17, 14, L"hardened_clay_stained_white"); - ADD_ICON(17, 15, L"hardened_clay_stained_yellow"); - - ADD_ICON(18, 0, L"glass_black"); - ADD_ICON(18, 1, L"glass_blue"); - ADD_ICON(18, 2, L"glass_brown"); - ADD_ICON(18, 3, L"glass_cyan"); - ADD_ICON(18, 4, L"glass_gray"); - ADD_ICON(18, 5, L"glass_green"); - ADD_ICON(18, 6, L"glass_light_blue"); - ADD_ICON(18, 7, L"glass_lime"); - ADD_ICON(18, 8, L"glass_magenta"); - ADD_ICON(18, 9, L"glass_orange"); - ADD_ICON(18, 10, L"glass_pink"); - ADD_ICON(18, 11, L"glass_purple"); - ADD_ICON(18, 12, L"glass_red"); - ADD_ICON(18, 13, L"glass_silver"); - ADD_ICON(18, 14, L"glass_white"); - ADD_ICON(18, 15, L"glass_yellow"); - - ADD_ICON(19, 0, L"glass_pane_top_black"); - ADD_ICON(19, 1, L"glass_pane_top_blue"); - ADD_ICON(19, 2, L"glass_pane_top_brown"); - ADD_ICON(19, 3, L"glass_pane_top_cyan"); - ADD_ICON(19, 4, L"glass_pane_top_gray"); - ADD_ICON(19, 5, L"glass_pane_top_green"); - ADD_ICON(19, 6, L"glass_pane_top_light_blue"); - ADD_ICON(19, 7, L"glass_pane_top_lime"); - ADD_ICON(19, 8, L"glass_pane_top_magenta"); - ADD_ICON(19, 9, L"glass_pane_top_orange"); - ADD_ICON(19, 10, L"glass_pane_top_pink"); - ADD_ICON(19, 11, L"glass_pane_top_purple"); - ADD_ICON(19, 12, L"glass_pane_top_red"); - ADD_ICON(19, 13, L"glass_pane_top_silver"); - ADD_ICON(19, 14, L"glass_pane_top_white"); - ADD_ICON(19, 15, L"glass_pane_top_yellow"); + ADD_ICON(16, 9, L"potatoes_stage0"); + ADD_ICON(16, 10, L"potatoes_stage1"); + ADD_ICON(16, 11, L"potatoes_stage2"); + ADD_ICON(16, 12, L"potatoes_stage3"); + ADD_ICON(16, 13, L"spruce_log_top"); + ADD_ICON(16, 14, L"jungle_log_top"); + ADD_ICON(16, 15, L"birch_log_top"); + + ADD_COL_TILE_ICON(17, 0, Tile::clayHardened, BLACK); + ADD_COL_TILE_ICON(17, 1, Tile::clayHardened, BLUE); + ADD_COL_TILE_ICON(17, 2, Tile::clayHardened, BROWN); + ADD_COL_TILE_ICON(17, 3, Tile::clayHardened, CYAN); + ADD_COL_TILE_ICON(17, 4, Tile::clayHardened, GRAY); + ADD_COL_TILE_ICON(17, 5, Tile::clayHardened, GREEN); + ADD_COL_TILE_ICON(17, 6, Tile::clayHardened, LIGHT_BLUE); + ADD_COL_TILE_ICON(17, 7, Tile::clayHardened, LIME); + ADD_COL_TILE_ICON(17, 8, Tile::clayHardened, MAGENTA); + ADD_COL_TILE_ICON(17, 9, Tile::clayHardened, ORANGE); + ADD_COL_TILE_ICON(17, 10, Tile::clayHardened, PINK); + ADD_COL_TILE_ICON(17, 11, Tile::clayHardened, PURPLE); + ADD_COL_TILE_ICON(17, 12, Tile::clayHardened, RED); + ADD_COL_TILE_ICON(17, 13, Tile::clayHardened, SILVER); + ADD_COL_TILE_ICON(17, 14, Tile::clayHardened, WHITE); + ADD_COL_TILE_ICON(17, 15, Tile::clayHardened, YELLOW); + + ADD_COL_TILE_ICON(18, 0, Tile::stained_glass, BLACK);//L"glass_black"); + ADD_COL_TILE_ICON(18, 1, Tile::stained_glass, BLUE);//L"glass_blue"); + ADD_COL_TILE_ICON(18, 2, Tile::stained_glass, BROWN);//L"glass_brown"); + ADD_COL_TILE_ICON(18, 3, Tile::stained_glass, CYAN);//L"glass_cyan"); + ADD_COL_TILE_ICON(18, 4, Tile::stained_glass, GRAY);//L"glass_gray"); + ADD_COL_TILE_ICON(18, 5, Tile::stained_glass, GREEN);//L"glass_green"); + ADD_COL_TILE_ICON(18, 6, Tile::stained_glass, LIGHT_BLUE);//L"glass_light_blue"); + ADD_COL_TILE_ICON(18, 7, Tile::stained_glass, LIME);//L"glass_lime"); + ADD_COL_TILE_ICON(18, 8, Tile::stained_glass, MAGENTA);//L"glass_magenta"); + ADD_COL_TILE_ICON(18, 9, Tile::stained_glass, ORANGE);//L"glass_orange"); + ADD_COL_TILE_ICON(18, 10, Tile::stained_glass, PINK);//L"glass_pink"); + ADD_COL_TILE_ICON(18, 11, Tile::stained_glass, PURPLE);//L"glass_purple"); + ADD_COL_TILE_ICON(18, 12, Tile::stained_glass, RED);//L"glass_red"); + ADD_COL_TILE_ICON(18, 13, Tile::stained_glass, SILVER);//L"glass_silver"); + ADD_COL_TILE_ICON(18, 14, Tile::stained_glass, WHITE);//L"glass_white"); + ADD_COL_TILE_ICON(18, 15, Tile::stained_glass, YELLOW);//L"glass_yellow"); + + ADD_ICON(19, 0, L"black_stained_glass_pane_top"); + ADD_ICON(19, 1, L"blue_stained_glass_pane_top"); + ADD_ICON(19, 2, L"brown_stained_glass_pane_top"); + ADD_ICON(19, 3, L"cyan_stained_glass_pane_top"); + ADD_ICON(19, 4, L"gray_stained_glass_pane_top"); + ADD_ICON(19, 5, L"green_stained_glass_pane_top"); + ADD_ICON(19, 6, L"light_blue_stained_glass_pane_top"); + ADD_ICON(19, 7, L"lime_stained_glass_pane_top"); + ADD_ICON(19, 8, L"magenta_stained_glass_pane_top"); + ADD_ICON(19, 9, L"orange_stained_glass_pane_top"); + ADD_ICON(19, 10, L"pink_stained_glass_pane_top"); + ADD_ICON(19, 11, L"purple_stained_glass_pane_top"); + ADD_ICON(19, 12, L"red_stained_glass_pane_top"); + ADD_ICON(19, 13, L"light_gray_stained_glass_pane_top"); + ADD_ICON(19, 14, L"white_stained_glass_pane_top"); + ADD_ICON(19, 15, L"yellow_stained_glass_pane_top"); } } diff --git a/Minecraft.Client/Settings.cpp b/Minecraft.Client/Settings.cpp index 9d93e6cbef..99da996894 100644 --- a/Minecraft.Client/Settings.cpp +++ b/Minecraft.Client/Settings.cpp @@ -81,8 +81,8 @@ void Settings::saveProperties() stream << "# MinecraftConsoles dedicated server properties\r\n"; for (unordered_map::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"; } } diff --git a/Minecraft.Client/TexturePack.h b/Minecraft.Client/TexturePack.h index 8e61342338..525e3f187d 100644 --- a/Minecraft.Client/TexturePack.h +++ b/Minecraft.Client/TexturePack.h @@ -52,7 +52,9 @@ class TexturePack 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 texturesByName) {} private: bool m_bHasAudio; diff --git a/Minecraft.Client/TexturePackRepository.cpp b/Minecraft.Client/TexturePackRepository.cpp index ef926d78bc..a8e80ac827 100644 --- a/Minecraft.Client/TexturePackRepository.cpp +++ b/Minecraft.Client/TexturePackRepository.cpp @@ -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) diff --git a/Minecraft.Client/Textures.cpp b/Minecraft.Client/Textures.cpp index ba7c028212..824a02654e 100644 --- a/Minecraft.Client/Textures.cpp +++ b/Minecraft.Client/Textures.cpp @@ -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) { diff --git a/Minecraft.Client/Windows64Media/7z.dll b/Minecraft.Client/Windows64Media/7z.dll new file mode 100644 index 0000000000..e81e08b993 Binary files /dev/null and b/Minecraft.Client/Windows64Media/7z.dll differ diff --git a/Minecraft.Client/stubs.h b/Minecraft.Client/stubs.h index 10ba2d0532..6fdda80bed 100644 --- a/Minecraft.Client/stubs.h +++ b/Minecraft.Client/stubs.h @@ -160,20 +160,11 @@ class Graphics 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 { diff --git a/Minecraft.Server/CMakeLists.txt b/Minecraft.Server/CMakeLists.txt index 52e5826eb4..a09e0d981c 100644 --- a/Minecraft.Server/CMakeLists.txt +++ b/Minecraft.Server/CMakeLists.txt @@ -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" > $<$>: # 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" > ) diff --git a/Minecraft.World/AnvilTile.cpp b/Minecraft.World/AnvilTile.cpp index 5d186c2855..5646c96328 100644 --- a/Minecraft.World/AnvilTile.cpp +++ b/Minecraft.World/AnvilTile.cpp @@ -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++) diff --git a/Minecraft.World/ArmorItem.cpp b/Minecraft.World/ArmorItem.cpp index 93d58cdd7b..daefb52483 100644 --- a/Minecraft.World/ArmorItem.cpp +++ b/Minecraft.World/ArmorItem.cpp @@ -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" }; diff --git a/Minecraft.World/ArmorItem.h b/Minecraft.World/ArmorItem.h index 92a40aea35..3105ddd6f3 100644 --- a/Minecraft.World/ArmorItem.h +++ b/Minecraft.World/ArmorItem.h @@ -14,9 +14,9 @@ class ArmorItem : public Item private: static const int healthPerSlot[]; - static const wstring LEATHER_OVERLAYS[] ; public: + static const wstring LEATHER_OVERLAYS[]; static const wstring TEXTURE_EMPTY_SLOTS[]; private: diff --git a/Minecraft.World/CMakeLists.txt b/Minecraft.World/CMakeLists.txt index e397bf2925..1aa7e8067d 100644 --- a/Minecraft.World/CMakeLists.txt +++ b/Minecraft.World/CMakeLists.txt @@ -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" ) diff --git a/Minecraft.World/CarrotTile.cpp b/Minecraft.World/CarrotTile.cpp index 8841e199b6..6e80ba8334 100644 --- a/Minecraft.World/CarrotTile.cpp +++ b/Minecraft.World/CarrotTile.cpp @@ -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)); - } -} \ No newline at end of file +// 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)); +// } +//} \ No newline at end of file diff --git a/Minecraft.World/CarrotTile.h b/Minecraft.World/CarrotTile.h index 82c1c02bdc..156b247558 100644 --- a/Minecraft.World/CarrotTile.h +++ b/Minecraft.World/CarrotTile.h @@ -15,7 +15,4 @@ class CarrotTile : public CropTile protected: int getBaseSeedId(); int getBasePlantId(); - -public: - void registerIcons(IconRegister *iconRegister); }; \ No newline at end of file diff --git a/Minecraft.World/ChestTile.cpp b/Minecraft.World/ChestTile.cpp index ff3c0b4063..f40e2ccd24 100644 --- a/Minecraft.World/ChestTile.cpp +++ b/Minecraft.World/ChestTile.cpp @@ -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"); } diff --git a/Minecraft.World/CocoaTile.cpp b/Minecraft.World/CocoaTile.cpp index 3df58eb847..ed80db6aa1 100644 --- a/Minecraft.World/CocoaTile.cpp +++ b/Minecraft.World/CocoaTile.cpp @@ -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() ) { diff --git a/Minecraft.World/ColoredTile.cpp b/Minecraft.World/ColoredTile.cpp index 6c8c171253..9d2f3f4416 100644 --- a/Minecraft.World/ColoredTile.cpp +++ b/Minecraft.World/ColoredTile.cpp @@ -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()); } } \ No newline at end of file diff --git a/Minecraft.World/ColoredTile.h b/Minecraft.World/ColoredTile.h index 19310dda3e..ca2000f404 100644 --- a/Minecraft.World/ColoredTile.h +++ b/Minecraft.World/ColoredTile.h @@ -17,5 +17,6 @@ class ColoredTile : public Tile virtual int getSpawnResourcesAuxValue(int data); static int getTileDataForItemAuxValue(int auxValue); static int getItemAuxValueForTileData(int data); + wstring getColoredIconName(int id); virtual void registerIcons(IconRegister *iconRegister); }; \ No newline at end of file diff --git a/Minecraft.World/Connection.cpp b/Minecraft.World/Connection.cpp index d445026678..5f744fac3c 100644 --- a/Minecraft.World/Connection.cpp +++ b/Minecraft.World/Connection.cpp @@ -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(this), readThreadName, READ_STACK_SIZE); writeThread = new C4JThread(runWrite, this, writeThreadName, WRITE_STACK_SIZE); diff --git a/Minecraft.World/ConsoleSaveFileOriginal.cpp b/Minecraft.World/ConsoleSaveFileOriginal.cpp index 8a7d1f9ec5..404cdce5b8 100644 --- a/Minecraft.World/ConsoleSaveFileOriginal.cpp +++ b/Minecraft.World/ConsoleSaveFileOriginal.cpp @@ -881,10 +881,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) diff --git a/Minecraft.World/CropTile.cpp b/Minecraft.World/CropTile.cpp index 1a16119968..377018cd64 100644 --- a/Minecraft.World/CropTile.cpp +++ b/Minecraft.World/CropTile.cpp @@ -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)); } } \ No newline at end of file diff --git a/Minecraft.World/CropTile.h b/Minecraft.World/CropTile.h index 165fd4af8e..7f56df0c38 100644 --- a/Minecraft.World/CropTile.h +++ b/Minecraft.World/CropTile.h @@ -27,6 +27,7 @@ class CropTile : public Bush virtual Icon *getTexture(int face, int data); virtual int getRenderShape(); protected: + int stages; virtual int getBaseSeedId(); virtual int getBasePlantId(); diff --git a/Minecraft.World/DetectorRailTile.cpp b/Minecraft.World/DetectorRailTile.cpp index ce35a59263..109784e910 100644 --- a/Minecraft.World/DetectorRailTile.cpp +++ b/Minecraft.World/DetectorRailTile.cpp @@ -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) diff --git a/Minecraft.World/DoorTile.cpp b/Minecraft.World/DoorTile.cpp index 8b70e6d97a..7699d58187 100644 --- a/Minecraft.World/DoorTile.cpp +++ b/Minecraft.World/DoorTile.cpp @@ -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); } diff --git a/Minecraft.World/DropperTile.cpp b/Minecraft.World/DropperTile.cpp index 180aec2acf..af527a4ab2 100644 --- a/Minecraft.World/DropperTile.cpp +++ b/Minecraft.World/DropperTile.cpp @@ -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"); } diff --git a/Minecraft.World/DyePowderItem.cpp b/Minecraft.World/DyePowderItem.cpp index 3392da9821..c32de38253 100644 --- a/Minecraft.World/DyePowderItem.cpp +++ b/Minecraft.World/DyePowderItem.cpp @@ -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()); } } \ No newline at end of file diff --git a/Minecraft.World/EnchantmentTableTile.cpp b/Minecraft.World/EnchantmentTableTile.cpp index a5c5184967..a1ba559004 100644 --- a/Minecraft.World/EnchantmentTableTile.cpp +++ b/Minecraft.World/EnchantmentTableTile.cpp @@ -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"); } diff --git a/Minecraft.World/FarmTile.cpp b/Minecraft.World/FarmTile.cpp index 39bf685f5d..a36e42be7c 100644 --- a/Minecraft.World/FarmTile.cpp +++ b/Minecraft.World/FarmTile.cpp @@ -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"); } diff --git a/Minecraft.World/File.cpp b/Minecraft.World/File.cpp index 11871e4260..cca01e3ee8 100644 --- a/Minecraft.World/File.cpp +++ b/Minecraft.World/File.cpp @@ -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::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 ); diff --git a/Minecraft.World/FileInputStream.cpp b/Minecraft.World/FileInputStream.cpp index 7c34a22f30..ca94cfceb7 100644 --- a/Minecraft.World/FileInputStream.cpp +++ b/Minecraft.World/FileInputStream.cpp @@ -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 diff --git a/Minecraft.World/FileOutputStream.cpp b/Minecraft.World/FileOutputStream.cpp index 58a0ecd96b..86a159ab58 100644 --- a/Minecraft.World/FileOutputStream.cpp +++ b/Minecraft.World/FileOutputStream.cpp @@ -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 diff --git a/Minecraft.World/FishingRodItem.cpp b/Minecraft.World/FishingRodItem.cpp index b9eafd1844..e46196259b 100644 --- a/Minecraft.World/FishingRodItem.cpp +++ b/Minecraft.World/FishingRodItem.cpp @@ -55,7 +55,7 @@ shared_ptr FishingRodItem::use(shared_ptr instance, void FishingRodItem::registerIcons(IconRegister *iconRegister) { - icon = iconRegister->registerIcon(getIconName() + L"_uncast"); + icon = iconRegister->registerIcon(getIconName()); emptyIcon = iconRegister->registerIcon(getIconName() + L"_cast"); } diff --git a/Minecraft.World/FurnaceTile.cpp b/Minecraft.World/FurnaceTile.cpp index d8856f4e36..a95c257385 100644 --- a/Minecraft.World/FurnaceTile.cpp +++ b/Minecraft.World/FurnaceTile.cpp @@ -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"); } diff --git a/Minecraft.World/GrassTile.cpp b/Minecraft.World/GrassTile.cpp index 9be44d0ebd..b6c1ecb708 100644 --- a/Minecraft.World/GrassTile.cpp +++ b/Minecraft.World/GrassTile.cpp @@ -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 diff --git a/Minecraft.World/HugeMushroomTile.cpp b/Minecraft.World/HugeMushroomTile.cpp index 8d3ef144da..10a328f6fb 100644 --- a/Minecraft.World/HugeMushroomTile.cpp +++ b/Minecraft.World/HugeMushroomTile.cpp @@ -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); } \ No newline at end of file diff --git a/Minecraft.World/Item.cpp b/Minecraft.World/Item.cpp index ffb310704c..13f412b4fd 100644 --- a/Minecraft.World/Item.cpp +++ b/Minecraft.World/Item.cpp @@ -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::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::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::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::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::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::helmet_leather = static_cast((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((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((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((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::chestplate_leather = static_cast((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((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((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((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::leggings_leather = static_cast((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((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((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((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::helmet_chain = static_cast((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((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((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((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::boots_leather = static_cast((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((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((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((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::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::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"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"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"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"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"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((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((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((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((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((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((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((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((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((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((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((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((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((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((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((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((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((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((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((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((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"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((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((new MapItem(102))->setIconName(L"map")->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_map)->setDescriptionId(IDS_ITEM_MAP)->setUseDescriptionId(IDS_DESC_MAP)); + Item::map = static_cast((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((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((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::diode_off)) ) ->setIconName(L"diode")->setDescriptionId(IDS_ITEM_DIODE)->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER); + Item::repeater = ( new TilePlanterItem(100, static_cast(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((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((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((new EmptyMapItem(139))->setIconName(L"map_empty")->setDescriptionId(IDS_ITEM_MAP_EMPTY)->setUseDescriptionId(IDS_DESC_MAP_EMPTY)); + Item::emptyMap = static_cast((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((new EnchantedBookItem(147))->setMaxStackSize(1)->setIconName(L"enchantedBook")->setDescriptionId(IDS_ITEM_ENCHANTED_BOOK)->setUseDescriptionId(IDS_DESC_ENCHANTED_BOOK)); + EnchantedBookItem::enchantedBook = static_cast((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);} diff --git a/Minecraft.World/LeafTile.cpp b/Minecraft.World/LeafTile.cpp index f8f5deae47..57039fea58 100644 --- a/Minecraft.World/LeafTile.cpp +++ b/Minecraft.World/LeafTile.cpp @@ -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"")); } } } diff --git a/Minecraft.World/MycelTile.cpp b/Minecraft.World/MycelTile.cpp index 76b742e341..24d029e908 100644 --- a/Minecraft.World/MycelTile.cpp +++ b/Minecraft.World/MycelTile.cpp @@ -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) diff --git a/Minecraft.World/NetherWartTile.cpp b/Minecraft.World/NetherWartTile.cpp index afe45aec5e..02caf6c8dc 100644 --- a/Minecraft.World/NetherWartTile.cpp +++ b/Minecraft.World/NetherWartTile.cpp @@ -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) ); } } diff --git a/Minecraft.World/PistonBaseTile.cpp b/Minecraft.World/PistonBaseTile.cpp index e8e2a7138b..b0cb5a93da 100644 --- a/Minecraft.World/PistonBaseTile.cpp +++ b/Minecraft.World/PistonBaseTile.cpp @@ -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; diff --git a/Minecraft.World/PotatoTile.cpp b/Minecraft.World/PotatoTile.cpp index 351c8c9803..0fcb873024 100644 --- a/Minecraft.World/PotatoTile.cpp +++ b/Minecraft.World/PotatoTile.cpp @@ -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(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) ); - } } \ No newline at end of file diff --git a/Minecraft.World/PotatoTile.h b/Minecraft.World/PotatoTile.h index 8ce5960a6a..58f054c9b6 100644 --- a/Minecraft.World/PotatoTile.h +++ b/Minecraft.World/PotatoTile.h @@ -19,5 +19,4 @@ class PotatoTile : public CropTile public: void spawnResources(Level *level, int x, int y, int z, int data, float odds, int playerBonus); - void registerIcons(IconRegister *iconRegister); }; \ No newline at end of file diff --git a/Minecraft.World/PotionItem.cpp b/Minecraft.World/PotionItem.cpp index fd156883df..b39355b1f0 100644 --- a/Minecraft.World/PotionItem.cpp +++ b/Minecraft.World/PotionItem.cpp @@ -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 > PotionItem::s_uniquePotionValues; diff --git a/Minecraft.World/PoweredRailTile.cpp b/Minecraft.World/PoweredRailTile.cpp index 9ebf629183..2e15dca81e 100644 --- a/Minecraft.World/PoweredRailTile.cpp +++ b/Minecraft.World/PoweredRailTile.cpp @@ -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) diff --git a/Minecraft.World/PumpkinTile.cpp b/Minecraft.World/PumpkinTile.cpp index da11001d8f..0063597b2b 100644 --- a/Minecraft.World/PumpkinTile.cpp +++ b/Minecraft.World/PumpkinTile.cpp @@ -163,7 +163,7 @@ void PumpkinTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptrregisterIcon(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"); } diff --git a/Minecraft.World/PumpkinTile.h b/Minecraft.World/PumpkinTile.h index 59b4d81956..15080378f8 100644 --- a/Minecraft.World/PumpkinTile.h +++ b/Minecraft.World/PumpkinTile.h @@ -13,10 +13,10 @@ class PumpkinTile : public DirectionalTile 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; diff --git a/Minecraft.World/QuartzBlockTile.cpp b/Minecraft.World/QuartzBlockTile.cpp index d0ab02d2a0..599242b609 100644 --- a/Minecraft.World/QuartzBlockTile.cpp +++ b/Minecraft.World/QuartzBlockTile.cpp @@ -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); } \ No newline at end of file diff --git a/Minecraft.World/RailTile.cpp b/Minecraft.World/RailTile.cpp index 798d248ca4..d3932d936e 100644 --- a/Minecraft.World/RailTile.cpp +++ b/Minecraft.World/RailTile.cpp @@ -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) diff --git a/Minecraft.World/RecordingItem.cpp b/Minecraft.World/RecordingItem.cpp index 3475263f56..6f24c8f11b 100644 --- a/Minecraft.World/RecordingItem.cpp +++ b/Minecraft.World/RecordingItem.cpp @@ -61,7 +61,7 @@ const Rarity *RecordingItem::getRarity(shared_ptr itemInstance) void RecordingItem::registerIcons(IconRegister *iconRegister) { - icon = iconRegister->registerIcon(L"record_" + recording); + icon = iconRegister->registerIcon(getIconName() + L"_" + recording); } RecordingItem *RecordingItem::getByName(const wstring &name) diff --git a/Minecraft.World/RedlightTile.cpp b/Minecraft.World/RedlightTile.cpp index bf4cc01fcb..9ccfd2fad8 100644 --- a/Minecraft.World/RedlightTile.cpp +++ b/Minecraft.World/RedlightTile.cpp @@ -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) diff --git a/Minecraft.World/SandStoneTile.cpp b/Minecraft.World/SandStoneTile.cpp index bd7309b9d1..d01fe4ee31 100644 --- a/Minecraft.World/SandStoneTile.cpp +++ b/Minecraft.World/SandStoneTile.cpp @@ -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 diff --git a/Minecraft.World/SandStoneTile.h b/Minecraft.World/SandStoneTile.h index ac6f9ff782..ff51da4f98 100644 --- a/Minecraft.World/SandStoneTile.h +++ b/Minecraft.World/SandStoneTile.h @@ -22,8 +22,8 @@ class SandStoneTile : public Tile private: static const wstring TEXTURE_TOP; static const wstring TEXTURE_BOTTOM; - static const wstring TEXTURE_NAMES[]; static const int SANDSTONE_TILE_TEXTURE_COUNT = 3; + static const wstring TEXTURE_NAMES[]; Icon **icons; Icon *iconTop; diff --git a/Minecraft.World/Sapling.cpp b/Minecraft.World/Sapling.cpp index c169a6082c..91ffc2c8df 100644 --- a/Minecraft.World/Sapling.cpp +++ b/Minecraft.World/Sapling.cpp @@ -161,9 +161,10 @@ bool Sapling::isSapling(Level *level, int x, int y, int z, int type) void Sapling::registerIcons(IconRegister *iconRegister) { icons = new Icon*[SAPLING_NAMES_SIZE]; + auto woodTile = (WoodTile*)Tile::wood; for (int i = 0; i < SAPLING_NAMES_SIZE; i++) { - icons[i] = iconRegister->registerIcon(TEXTURE_NAMES[i]); + icons[i] = iconRegister->registerIcon(woodTile->TEXTURE_NAMES[i] + L"_sapling"); } } diff --git a/Minecraft.World/SmoothStoneBrickTile.cpp b/Minecraft.World/SmoothStoneBrickTile.cpp index a42af97be5..4f351123eb 100644 --- a/Minecraft.World/SmoothStoneBrickTile.cpp +++ b/Minecraft.World/SmoothStoneBrickTile.cpp @@ -2,7 +2,7 @@ #include "SmoothStoneBrickTile.h" #include "net.minecraft.world.h" -const wstring SmoothStoneBrickTile::TEXTURE_NAMES[] = {L"", L"mossy", L"cracked", L"carved"}; +const wstring SmoothStoneBrickTile::TEXTURE_NAMES[] = {L"", L"mossy", L"cracked", L"chiseled"}; const unsigned int SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES[SMOOTH_STONE_BRICK_NAMES_LENGTH] = { IDS_TILE_STONE_BRICK_SMOOTH, IDS_TILE_STONE_BRICK_SMOOTH_MOSSY, @@ -39,7 +39,7 @@ void SmoothStoneBrickTile::registerIcons(IconRegister *iconRegister) for (int i = 0; i < SMOOTH_STONE_BRICK_NAMES_LENGTH; i++) { wstring name = getIconName(); - if (!TEXTURE_NAMES[i].empty() ) name += L"_" + TEXTURE_NAMES[i]; + if (!TEXTURE_NAMES[i].empty() ) name = TEXTURE_NAMES[i] + L"_" + name; icons[i] = iconRegister->registerIcon(name); } } \ No newline at end of file diff --git a/Minecraft.World/StainedGlassBlock.cpp b/Minecraft.World/StainedGlassBlock.cpp index 3fae3d46fb..dc5992eb68 100644 --- a/Minecraft.World/StainedGlassBlock.cpp +++ b/Minecraft.World/StainedGlassBlock.cpp @@ -34,7 +34,9 @@ void StainedGlassBlock::registerIcons(IconRegister *iconRegister) { for (int i = 0; i < ICONS_LENGTH; i++) { - ICONS[i] = iconRegister->registerIcon(getIconName() + L"_" + DyePowderItem::COLOR_TEXTURES[getItemAuxValueForBlockData(i)]); + int val = getItemAuxValueForBlockData(i); + auto colorName = (val != DyePowderItem::SILVER ? DyePowderItem::COLOR_TEXTURES[val] : L"light_gray"); + ICONS[i] = iconRegister->registerIcon(colorName + L"_" + getIconName()); } } diff --git a/Minecraft.World/StainedGlassPaneBlock.cpp b/Minecraft.World/StainedGlassPaneBlock.cpp index 086d8ae54e..e86d30d936 100644 --- a/Minecraft.World/StainedGlassPaneBlock.cpp +++ b/Minecraft.World/StainedGlassPaneBlock.cpp @@ -46,7 +46,9 @@ void StainedGlassPaneBlock::registerIcons(IconRegister *iconRegister) ThinFenceTile::registerIcons(iconRegister); for (int i = 0; i < ICONS_COUNT; i++) { - ICONS[i] = iconRegister->registerIcon(getIconName() + L"_" + DyePowderItem::COLOR_TEXTURES[getItemAuxValueForBlockData(i)]); - EDGE_ICONS[i] = iconRegister->registerIcon(getIconName() + L"_pane_top_" + DyePowderItem::COLOR_TEXTURES[getItemAuxValueForBlockData(i)]); + int val = getItemAuxValueForBlockData(i); + auto colorName = (val != DyePowderItem::SILVER ? DyePowderItem::COLOR_TEXTURES[val] : L"light_gray"); + ICONS[i] = iconRegister->registerIcon(colorName + L"_" + getIconName()); + EDGE_ICONS[i] = iconRegister->registerIcon(colorName + L"_" + getIconName() + L"_pane_top"); } } \ No newline at end of file diff --git a/Minecraft.World/StemTile.cpp b/Minecraft.World/StemTile.cpp index 476b643cf5..aa37ef2d2c 100644 --- a/Minecraft.World/StemTile.cpp +++ b/Minecraft.World/StemTile.cpp @@ -219,8 +219,8 @@ int StemTile::cloneTileId(Level *level, int x, int y, int z) void StemTile::registerIcons(IconRegister *iconRegister) { - icon = iconRegister->registerIcon(L"stem_straight"); - iconAngled = iconRegister->registerIcon(TEXTURE_ANGLED); + icon = iconRegister->registerIcon(L"pumpkin_stem_disconnected"); + iconAngled = iconRegister->registerIcon(L"attached_pumpkin_stem"); } Icon *StemTile::getAngledTexture() diff --git a/Minecraft.World/StoneSlabTile.cpp b/Minecraft.World/StoneSlabTile.cpp index 10f1ee71c3..cfa6503399 100644 --- a/Minecraft.World/StoneSlabTile.cpp +++ b/Minecraft.World/StoneSlabTile.cpp @@ -54,8 +54,8 @@ Icon *StoneSlabTile::getTexture(int face, int data) void StoneSlabTile::registerIcons(IconRegister *iconRegister) { - icon = iconRegister->registerIcon(L"stoneslab_top"); - iconSide = iconRegister->registerIcon(L"stoneslab_side"); + icon = iconRegister->registerIcon(getIconName()); + iconSide = iconRegister->registerIcon(getIconName() + L"_slab_side"); } int StoneSlabTile::getResource(int data, Random *random, int playerBonusLevel) diff --git a/Minecraft.World/StringHelpers.cpp b/Minecraft.World/StringHelpers.cpp index b56a85f140..d95f1e1aac 100644 --- a/Minecraft.World/StringHelpers.cpp +++ b/Minecraft.World/StringHelpers.cpp @@ -46,13 +46,11 @@ wstring convStringToWstring(const string& converting) return converted; } -// Convert for filename wstrings to a straight character pointer for Xbox APIs. The returned string is only valid until -// this function is called again, and it isn't thread-safe etc. as I'm just storing the returned name in a local static -// to save having to clear it up everywhere this is used. -const char *wstringtofilename(const wstring& name) +const std::string wstringtofilename(const wstring& name) { - static char buf[256]; assert(name.length()<256); + std::string buf; + buf.reserve(name.length()); for(unsigned int i = 0; i < name.length(); i++ ) { wchar_t c = name[i]; @@ -62,23 +60,36 @@ const char *wstringtofilename(const wstring& name) if(c=='/') c='\\'; #endif assert(c<128); // Will we have to do any conversion of non-ASCII characters in filenames? - buf[i] = static_cast(c); + buf += static_cast(c); + } + return buf; +} + +const std::string wstringtostring(const wstring& name) +{ + assert(name.length() < 256); + std::string buf; + buf.reserve(name.length()); + for (unsigned int i = 0; i < name.length(); i++) + { + wchar_t c = name[i]; + assert(c < 128); // Will we have to do any conversion of non-ASCII characters in filenames? + buf += static_cast(c); } - buf[name.length()] = 0; return buf; } -const char *wstringtochararray(const wstring& name) +const vector wstringtochararray(const wstring& name) { - static char buf[256]; assert(name.length()<256); + vector buf; + buf.reserve(name.length()); for(unsigned int i = 0; i < name.length(); i++ ) { wchar_t c = name[i]; assert(c<128); // Will we have to do any conversion of non-ASCII characters in filenames? buf[i] = static_cast(c); } - buf[name.length()] = 0; return buf; } diff --git a/Minecraft.World/StringHelpers.h b/Minecraft.World/StringHelpers.h index dee676bae8..4844313ebb 100644 --- a/Minecraft.World/StringHelpers.h +++ b/Minecraft.World/StringHelpers.h @@ -23,8 +23,9 @@ template T _fromHEXString(const std::wstring& s) } wstring convStringToWstring(const string& converting); -const char *wstringtofilename(const wstring& name); -const char *wstringtochararray(const wstring& name); +const std::string wstringtofilename(const wstring& name); +const std::string wstringtostring(const wstring& name); +const vector wstringtochararray(const wstring& name); wstring filenametowstring(const char *name); std::vector &stringSplit(const std::wstring &s, wchar_t delim, std::vector &elems); diff --git a/Minecraft.World/TallGrass.cpp b/Minecraft.World/TallGrass.cpp index 337e343d20..962f286079 100644 --- a/Minecraft.World/TallGrass.cpp +++ b/Minecraft.World/TallGrass.cpp @@ -12,7 +12,7 @@ const unsigned int TallGrass::TALL_GRASS_TILE_NAMES[TALL_GRASS_TILE_NAMES_LENGTH IDS_TILE_FERN, }; -const wstring TallGrass::TEXTURE_NAMES[] = {L"deadbush", L"tallgrass", L"fern"}; +const wstring TallGrass::TEXTURE_NAMES[] = {L"dead_bush", L"short_grass", L"fern"}; TallGrass::TallGrass(int id) : Bush(id, Material::replaceable_plant) { diff --git a/Minecraft.World/TheEndPortalFrameTile.cpp b/Minecraft.World/TheEndPortalFrameTile.cpp index 80e78f49d8..7364d9fcc6 100644 --- a/Minecraft.World/TheEndPortalFrameTile.cpp +++ b/Minecraft.World/TheEndPortalFrameTile.cpp @@ -28,9 +28,9 @@ Icon *TheEndPortalFrameTile::getTexture(int face, int data) void TheEndPortalFrameTile::registerIcons(IconRegister *iconRegister) { - icon = iconRegister->registerIcon(L"endframe_side"); - iconTop = iconRegister->registerIcon(L"endframe_top"); - iconEye = iconRegister->registerIcon(L"endframe_eye"); + icon = iconRegister->registerIcon(getIconName() + L"_side"); + iconTop = iconRegister->registerIcon(getIconName() + L"_top"); + iconEye = iconRegister->registerIcon(getIconName() + L"_eye"); } Icon *TheEndPortalFrameTile::getEye() diff --git a/Minecraft.World/Tile.cpp b/Minecraft.World/Tile.cpp index de113714db..09574e83e7 100644 --- a/Minecraft.World/Tile.cpp +++ b/Minecraft.World/Tile.cpp @@ -285,37 +285,37 @@ void Tile::staticCtor() Tile::lapisBlock = (new Tile(22, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_lapis)->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_STONE)->setIconName(L"lapis_block")->setDescriptionId(IDS_TILE_BLOCK_LAPIS)->setUseDescriptionId(IDS_DESC_BLOCK_LAPIS); Tile::dispenser = (new DispenserTile(23)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_redstoneContainer, Item::eMaterial_undefined)->setDestroyTime(3.5f)->setSoundType(Tile::SOUND_STONE)->setIconName(L"dispenser")->setDescriptionId(IDS_TILE_DISPENSER)->sendTileData()->setUseDescriptionId(IDS_DESC_DISPENSER); Tile::sandStone = (new SandStoneTile(24)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_sand)->setSoundType(Tile::SOUND_STONE)->setDestroyTime(0.8f)->sendTileData()->setIconName(L"sandstone")->setDescriptionId(IDS_TILE_SANDSTONE)->setUseDescriptionId(IDS_DESC_SANDSTONE)->sendTileData(); - Tile::noteblock = (new NoteBlockTile(25)) ->setDestroyTime(0.8f)->setIconName(L"noteblock")->setDescriptionId(IDS_TILE_MUSIC_BLOCK)->sendTileData()->setUseDescriptionId(IDS_DESC_NOTEBLOCK); + Tile::noteblock = (new NoteBlockTile(25)) ->setDestroyTime(0.8f)->setIconName(L"note_block")->setDescriptionId(IDS_TILE_MUSIC_BLOCK)->sendTileData()->setUseDescriptionId(IDS_DESC_NOTEBLOCK); Tile::bed = (new BedTile(26)) ->setDestroyTime(0.2f)->setIconName(L"bed")->setDescriptionId(IDS_TILE_BED)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_BED); - Tile::goldenRail = (new PoweredRailTile(27)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, Item::eMaterial_gold)->setDestroyTime(0.7f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"rail_golden")->setDescriptionId(IDS_TILE_GOLDEN_RAIL)->sendTileData()->setUseDescriptionId(IDS_DESC_POWEREDRAIL)->disableMipmap(); - Tile::detectorRail = (new DetectorRailTile(28)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, Item::eMaterial_detector)->setDestroyTime(0.7f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"rail_detector")->setDescriptionId(IDS_TILE_DETECTOR_RAIL)->sendTileData()->setUseDescriptionId(IDS_DESC_DETECTORRAIL)->disableMipmap(); + Tile::goldenRail = (new PoweredRailTile(27)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, Item::eMaterial_gold)->setDestroyTime(0.7f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"powered_rail")->setDescriptionId(IDS_TILE_GOLDEN_RAIL)->sendTileData()->setUseDescriptionId(IDS_DESC_POWEREDRAIL)->disableMipmap(); + Tile::detectorRail = (new DetectorRailTile(28)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, Item::eMaterial_detector)->setDestroyTime(0.7f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"detector_rail")->setDescriptionId(IDS_TILE_DETECTOR_RAIL)->sendTileData()->setUseDescriptionId(IDS_DESC_DETECTORRAIL)->disableMipmap(); Tile::pistonStickyBase = static_cast((new PistonBaseTile(29, true))->setBaseItemTypeAndMaterial(Item::eBaseItemType_piston, Item::eMaterial_stickypiston)->setIconName(L"pistonStickyBase")->setDescriptionId(IDS_TILE_PISTON_STICK_BASE)->setUseDescriptionId(IDS_DESC_STICKY_PISTON)->sendTileData()); - Tile::web = (new WebTile(30)) ->setLightBlock(1)->setDestroyTime(4.0f)->setIconName(L"web")->setDescriptionId(IDS_TILE_WEB)->setUseDescriptionId(IDS_DESC_WEB); + Tile::web = (new WebTile(30)) ->setLightBlock(1)->setDestroyTime(4.0f)->setIconName(L"cobweb")->setDescriptionId(IDS_TILE_WEB)->setUseDescriptionId(IDS_DESC_WEB); - Tile::tallgrass = static_cast((new TallGrass(31))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"tallgrass")->setDescriptionId(IDS_TILE_TALL_GRASS)->setUseDescriptionId(IDS_DESC_TALL_GRASS)->disableMipmap()); - Tile::deadBush = static_cast((new DeadBushTile(32))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"deadbush")->setDescriptionId(IDS_TILE_DEAD_BUSH)->setUseDescriptionId(IDS_DESC_DEAD_BUSH)->disableMipmap()); + Tile::tallgrass = static_cast((new TallGrass(31))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"short_grass")->setDescriptionId(IDS_TILE_TALL_GRASS)->setUseDescriptionId(IDS_DESC_TALL_GRASS)->disableMipmap()); + Tile::deadBush = static_cast((new DeadBushTile(32))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"dead_bush")->setDescriptionId(IDS_TILE_DEAD_BUSH)->setUseDescriptionId(IDS_DESC_DEAD_BUSH)->disableMipmap()); Tile::pistonBase = static_cast((new PistonBaseTile(33, false))->setBaseItemTypeAndMaterial(Item::eBaseItemType_piston, Item::eMaterial_piston)->setIconName(L"pistonBase")->setDescriptionId(IDS_TILE_PISTON_BASE)->setUseDescriptionId(IDS_DESC_PISTON)->sendTileData()); Tile::pistonExtension = static_cast((new PistonExtensionTile(34))->setDescriptionId(IDS_TILE_PISTON_BASE)->setUseDescriptionId(-1)->sendTileData()); - Tile::wool = (new ColoredTile(35, Material::cloth)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_cloth, Item::eMaterial_cloth)->setDestroyTime(0.8f)->setSoundType(Tile::SOUND_CLOTH)->setIconName(L"wool_colored")->setDescriptionId(IDS_TILE_CLOTH)->sendTileData()->setUseDescriptionId(IDS_DESC_WOOL); + Tile::wool = (new ColoredTile(35, Material::cloth)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_cloth, Item::eMaterial_cloth)->setDestroyTime(0.8f)->setSoundType(Tile::SOUND_CLOTH)->setIconName(L"wool")->setDescriptionId(IDS_TILE_CLOTH)->sendTileData()->setUseDescriptionId(IDS_DESC_WOOL); Tile::pistonMovingPiece = static_cast((new PistonMovingPiece(36))->setDescriptionId(IDS_TILE_PISTON_BASE)->setUseDescriptionId(-1)); - Tile::flower = static_cast((new Bush(37))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"flower_dandelion")->setDescriptionId(IDS_TILE_FLOWER)->setUseDescriptionId(IDS_DESC_FLOWER)->disableMipmap()); - Tile::rose = static_cast((new Bush(38))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"flower_rose")->setDescriptionId(IDS_TILE_ROSE)->setUseDescriptionId(IDS_DESC_FLOWER)->disableMipmap()); - Tile::mushroom_brown = static_cast((new Mushroom(39))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setLightEmission(2 / 16.0f)->setIconName(L"mushroom_brown")->setDescriptionId(IDS_TILE_MUSHROOM)->setUseDescriptionId(IDS_DESC_MUSHROOM)->disableMipmap()); - Tile::mushroom_red = static_cast((new Mushroom(40))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"mushroom_red")->setDescriptionId(IDS_TILE_MUSHROOM)->setUseDescriptionId(IDS_DESC_MUSHROOM)->disableMipmap()); + Tile::flower = static_cast((new Bush(37))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"dandelion")->setDescriptionId(IDS_TILE_FLOWER)->setUseDescriptionId(IDS_DESC_FLOWER)->disableMipmap()); + Tile::rose = static_cast((new Bush(38))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"poppy")->setDescriptionId(IDS_TILE_ROSE)->setUseDescriptionId(IDS_DESC_FLOWER)->disableMipmap()); + Tile::mushroom_brown = static_cast((new Mushroom(39))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setLightEmission(2 / 16.0f)->setIconName(L"brown_mushroom")->setDescriptionId(IDS_TILE_MUSHROOM)->setUseDescriptionId(IDS_DESC_MUSHROOM)->disableMipmap()); + Tile::mushroom_red = static_cast((new Mushroom(40))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"red_mushroom")->setDescriptionId(IDS_TILE_MUSHROOM)->setUseDescriptionId(IDS_DESC_MUSHROOM)->disableMipmap()); Tile::goldBlock = (new MetalTile(41)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_gold)->setDestroyTime(3.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_METAL)->setIconName(L"gold_block")->setDescriptionId(IDS_TILE_BLOCK_GOLD)->setUseDescriptionId(IDS_DESC_BLOCK_GOLD); Tile::ironBlock = (new MetalTile(42)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_iron)->setDestroyTime(5.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_METAL)->setIconName(L"iron_block")->setDescriptionId(IDS_TILE_BLOCK_IRON)->setUseDescriptionId(IDS_DESC_BLOCK_IRON); - Tile::stoneSlab = static_cast((new StoneSlabTile(Tile::stoneSlab_Id, true))->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"stoneSlab")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_SLAB)); - Tile::stoneSlabHalf = static_cast((new StoneSlabTile(Tile::stoneSlabHalf_Id, false))->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"stoneSlab")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_HALFSLAB)); - Tile::redBrick = (new Tile(45, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_brick)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"brick")->setDescriptionId(IDS_TILE_BRICK)->setUseDescriptionId(IDS_DESC_BRICK); + Tile::stoneSlab = static_cast((new StoneSlabTile(Tile::stoneSlab_Id, true))->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"smooth_stone")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_SLAB)); + Tile::stoneSlabHalf = static_cast((new StoneSlabTile(Tile::stoneSlabHalf_Id, false))->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, Item::eMaterial_stone)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"smooth_stone")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_HALFSLAB)); + Tile::redBrick = (new Tile(45, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_brick)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"bricks")->setDescriptionId(IDS_TILE_BRICK)->setUseDescriptionId(IDS_DESC_BRICK); Tile::tnt = (new TntTile(46)) ->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"tnt")->setDescriptionId(IDS_TILE_TNT)->setUseDescriptionId(IDS_DESC_TNT); Tile::bookshelf = (new BookshelfTile(47)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, Item::eMaterial_bookshelf)->setDestroyTime(1.5f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"bookshelf")->setDescriptionId(IDS_TILE_BOOKSHELF)->setUseDescriptionId(IDS_DESC_BOOKSHELF); - Tile::mossyCobblestone = (new Tile(48, Material::stone)) ->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"cobblestone_mossy")->setDescriptionId(IDS_TILE_STONE_MOSS)->setUseDescriptionId(IDS_DESC_MOSS_STONE); + Tile::mossyCobblestone = (new Tile(48, Material::stone)) ->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"mossy_cobblestone")->setDescriptionId(IDS_TILE_STONE_MOSS)->setUseDescriptionId(IDS_DESC_MOSS_STONE); Tile::obsidian = (new ObsidianTile(49)) ->setDestroyTime(50.0f)->setExplodeable(2000)->setSoundType(Tile::SOUND_STONE)->setIconName(L"obsidian")->setDescriptionId(IDS_TILE_OBSIDIAN)->setUseDescriptionId(IDS_DESC_OBSIDIAN); - Tile::torch = (new TorchTile(50)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, Item::eMaterial_wood)->setDestroyTime(0.0f)->setLightEmission(15 / 16.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"torch_on")->setDescriptionId(IDS_TILE_TORCH)->setUseDescriptionId(IDS_DESC_TORCH)->disableMipmap(); + Tile::torch = (new TorchTile(50)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, Item::eMaterial_wood)->setDestroyTime(0.0f)->setLightEmission(15 / 16.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"torch")->setDescriptionId(IDS_TILE_TORCH)->setUseDescriptionId(IDS_DESC_TORCH)->disableMipmap(); Tile::fire = static_cast(((new FireTile(51))->setDestroyTime(0.0f)->setLightEmission(1.0f)->setSoundType(Tile::SOUND_WOOD))->setIconName(L"fire")->setDescriptionId(IDS_TILE_FIRE)->setNotCollectStatistics()->setUseDescriptionId(-1)); - Tile::mobSpawner = (new MobSpawnerTile(52)) ->setDestroyTime(5.0f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"mob_spawner")->setDescriptionId(IDS_TILE_MOB_SPAWNER)->setNotCollectStatistics()->setUseDescriptionId(IDS_DESC_MOB_SPAWNER); + Tile::mobSpawner = (new MobSpawnerTile(52)) ->setDestroyTime(5.0f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"spawner")->setDescriptionId(IDS_TILE_MOB_SPAWNER)->setNotCollectStatistics()->setUseDescriptionId(IDS_DESC_MOB_SPAWNER); Tile::stairs_wood = (new StairTile(53, Tile::wood,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_wood) ->setIconName(L"stairsWood")->setDescriptionId(IDS_TILE_STAIRS_WOOD) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::chest = static_cast((new ChestTile(54, ChestTile::TYPE_BASIC))->setBaseItemTypeAndMaterial(Item::eBaseItemType_chest, Item::eMaterial_wood)->setDestroyTime(2.5f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"chest")->setDescriptionId(IDS_TILE_CHEST)->sendTileData()->setUseDescriptionId(IDS_DESC_CHEST)); Tile::redStoneDust = static_cast((new RedStoneDustTile(55))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_NORMAL)->setIconName(L"redstone_dust")->setDescriptionId(IDS_TILE_REDSTONE_DUST)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONE_DUST)); @@ -328,20 +328,20 @@ void Tile::staticCtor() Tile::furnace = (new FurnaceTile(61, false)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_device, Item::eMaterial_stone)->setDestroyTime(3.5f)->setSoundType(Tile::SOUND_STONE)->setIconName(L"furnace")->setDescriptionId(IDS_TILE_FURNACE)->sendTileData()->setUseDescriptionId(IDS_DESC_FURNACE); Tile::furnace_lit = (new FurnaceTile(62, true)) ->setDestroyTime(3.5f)->setSoundType(Tile::SOUND_STONE)->setLightEmission(14 / 16.0f)->setIconName(L"furnace")->setDescriptionId(IDS_TILE_FURNACE)->sendTileData()->setUseDescriptionId(IDS_DESC_FURNACE); Tile::sign = (new SignTile(63, eTYPE_SIGNTILEENTITY, true)) ->setDestroyTime(1.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"sign")->setDescriptionId(IDS_TILE_SIGN)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_SIGN); - Tile::door_wood = (new DoorTile(64, Material::wood)) ->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"door_wood")->setDescriptionId(IDS_TILE_DOOR_WOOD)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); + Tile::door_wood = (new DoorTile(64, Material::wood)) ->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"oak_door")->setDescriptionId(IDS_TILE_DOOR_WOOD)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_WOOD); Tile::ladder = (new LadderTile(65)) ->setDestroyTime(0.4f)->setSoundType(Tile::SOUND_LADDER)->setIconName(L"ladder")->setDescriptionId(IDS_TILE_LADDER)->sendTileData()->setUseDescriptionId(IDS_DESC_LADDER)->disableMipmap(); - Tile::rail = (new RailTile(66)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, Item::eMaterial_iron)->setDestroyTime(0.7f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"rail_normal")->setDescriptionId(IDS_TILE_RAIL)->sendTileData()->setUseDescriptionId(IDS_DESC_RAIL)->disableMipmap(); + Tile::rail = (new RailTile(66)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_rail, Item::eMaterial_iron)->setDestroyTime(0.7f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"rail")->setDescriptionId(IDS_TILE_RAIL)->sendTileData()->setUseDescriptionId(IDS_DESC_RAIL)->disableMipmap(); Tile::stairs_stone =(new StairTile(67, Tile::cobblestone,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_stone) ->setIconName(L"stairsStone")->setDescriptionId(IDS_TILE_STAIRS_STONE) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::wallSign = (new SignTile(68, eTYPE_SIGNTILEENTITY, false)) ->setDestroyTime(1.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"sign")->setDescriptionId(IDS_TILE_SIGN)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_SIGN); Tile::lever = (new LeverTile(69)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_lever, Item::eMaterial_wood)->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"lever")->setDescriptionId(IDS_TILE_LEVER)->sendTileData()->setUseDescriptionId(IDS_DESC_LEVER); Tile::pressurePlate_stone = (Tile *)(new PressurePlateTile(70, L"stone", Material::stone, PressurePlateTile::mobs)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_stone)->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_STONE)->setDescriptionId(IDS_TILE_PRESSURE_PLATE)->sendTileData()->setUseDescriptionId(IDS_DESC_PRESSUREPLATE); - Tile::door_iron = (new DoorTile(71, Material::metal)) ->setDestroyTime(5.0f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"door_iron")->setDescriptionId(IDS_TILE_DOOR_IRON)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_IRON); - Tile::pressurePlate_wood = (new PressurePlateTile(72, L"planks_oak", Material::wood, PressurePlateTile::everything)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_wood)->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_WOOD)->setDescriptionId(IDS_TILE_PRESSURE_PLATE)->sendTileData()->setUseDescriptionId(IDS_DESC_PRESSUREPLATE); + Tile::door_iron = (new DoorTile(71, Material::metal)) ->setDestroyTime(5.0f)->setSoundType(Tile::SOUND_METAL)->setIconName(L"iron_door")->setDescriptionId(IDS_TILE_DOOR_IRON)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_DOOR_IRON); + Tile::pressurePlate_wood = (new PressurePlateTile(72, L"oak_planks", Material::wood, PressurePlateTile::everything)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_wood)->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_WOOD)->setDescriptionId(IDS_TILE_PRESSURE_PLATE)->sendTileData()->setUseDescriptionId(IDS_DESC_PRESSUREPLATE); Tile::redStoneOre = (new RedStoneOreTile(73,false)) ->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_STONE)->setIconName(L"redstone_ore")->setDescriptionId(IDS_TILE_ORE_REDSTONE)->sendTileData()->setUseDescriptionId(IDS_DESC_ORE_REDSTONE); Tile::redStoneOre_lit = (new RedStoneOreTile(74, true)) ->setLightEmission(10 / 16.0f)->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_STONE)->setIconName(L"redstone_ore")->setDescriptionId(IDS_TILE_ORE_REDSTONE)->sendTileData()->setUseDescriptionId(IDS_DESC_ORE_REDSTONE); Tile::redstoneTorch_off = (new NotGateTile(75, false)) ->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"redstone_torch_off")->setDescriptionId(IDS_TILE_NOT_GATE)->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONETORCH)->disableMipmap(); - Tile::redstoneTorch_on = (new NotGateTile(76, true)) ->setDestroyTime(0.0f)->setLightEmission(8 / 16.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"redstone_torch_on")->setDescriptionId(IDS_TILE_NOT_GATE)->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONETORCH)->disableMipmap(); + Tile::redstoneTorch_on = (new NotGateTile(76, true)) ->setDestroyTime(0.0f)->setLightEmission(8 / 16.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"redstone_torch")->setDescriptionId(IDS_TILE_NOT_GATE)->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONETORCH)->disableMipmap(); Tile::button = (new StoneButtonTile(77)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_button, Item::eMaterial_stone)->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_STONE)->setIconName(L"button")->setDescriptionId(IDS_TILE_BUTTON)->sendTileData()->setUseDescriptionId(IDS_DESC_BUTTON); Tile::topSnow = (new TopSnowTile(78)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_snow)->setDestroyTime(0.1f)->setSoundType(Tile::SOUND_SNOW)->setIconName(L"snow")->setDescriptionId(IDS_TILE_SNOW)->setUseDescriptionId(IDS_DESC_TOP_SNOW)->sendTileData()->setLightBlock(0); Tile::ice = (new IceTile(79)) ->setDestroyTime(0.5f)->setLightBlock(3)->setSoundType(Tile::SOUND_GLASS)->setIconName(L"ice")->setDescriptionId(IDS_TILE_ICE)->setUseDescriptionId(IDS_DESC_ICE); @@ -349,9 +349,9 @@ void Tile::staticCtor() Tile::cactus = (new CactusTile(81)) ->setDestroyTime(0.4f)->setSoundType(Tile::SOUND_CLOTH)->setIconName(L"cactus")->setDescriptionId(IDS_TILE_CACTUS)->setUseDescriptionId(IDS_DESC_CACTUS)->disableMipmap(); Tile::clay = (new ClayTile(82)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_clay)->setDestroyTime(0.6f)->setSoundType(Tile::SOUND_GRAVEL)->setIconName(L"clay")->setDescriptionId(IDS_TILE_CLAY)->setUseDescriptionId(IDS_DESC_CLAY_TILE); - Tile::reeds = (new ReedTile(83)) ->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"reeds")->setDescriptionId(IDS_TILE_REEDS)->setNotCollectStatistics()->setUseDescriptionId(IDS_DESC_REEDS)->disableMipmap(); + Tile::reeds = (new ReedTile(83)) ->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"sugar_cane")->setDescriptionId(IDS_TILE_REEDS)->setNotCollectStatistics()->setUseDescriptionId(IDS_DESC_REEDS)->disableMipmap(); Tile::jukebox = (new JukeboxTile(84)) ->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(Tile::SOUND_STONE)->setIconName(L"jukebox")->setDescriptionId(IDS_TILE_JUKEBOX)->sendTileData()->setUseDescriptionId(IDS_DESC_JUKEBOX); - Tile::fence = (new FenceTile(85, L"planks_oak", Material::wood)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_WOOD)->setDescriptionId(IDS_TILE_FENCE)->setUseDescriptionId(IDS_DESC_FENCE); + Tile::fence = (new FenceTile(85, L"oak_planks", Material::wood)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_WOOD)->setDescriptionId(IDS_TILE_FENCE)->setUseDescriptionId(IDS_DESC_FENCE); Tile::pumpkin = (new PumpkinTile(86, false)) ->setDestroyTime(1.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"pumpkin")->setDescriptionId(IDS_TILE_PUMPKIN)->sendTileData()->setUseDescriptionId(IDS_DESC_PUMPKIN); Tile::netherRack = (new NetherrackTile(87)) ->setDestroyTime(0.4f)->setSoundType(Tile::SOUND_STONE)->setIconName(L"netherrack")->setDescriptionId(IDS_TILE_HELL_ROCK)->setUseDescriptionId(IDS_DESC_HELL_ROCK); Tile::soulsand = (new SoulSandTile(88)) ->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_SAND)->setIconName(L"soul_sand")->setDescriptionId(IDS_TILE_HELL_SAND)->setUseDescriptionId(IDS_DESC_HELL_SAND); @@ -360,12 +360,12 @@ void Tile::staticCtor() Tile::litPumpkin = (new PumpkinTile(91, true)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_torch, Item::eMaterial_pumpkin)->setDestroyTime(1.0f)->setSoundType(Tile::SOUND_WOOD)->setLightEmission(1.0f)->setIconName(L"pumpkin")->setDescriptionId(IDS_TILE_LIT_PUMPKIN)->sendTileData()->setUseDescriptionId(IDS_DESC_JACKOLANTERN); Tile::cake = (new CakeTile(92)) ->setDestroyTime(0.5f)->setSoundType(Tile::SOUND_CLOTH)->setIconName(L"cake")->setDescriptionId(IDS_TILE_CAKE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_CAKE); - Tile::diode_off = static_cast((new RepeaterTile(93, false))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"repeater_off")->setDescriptionId(IDS_ITEM_DIODE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER)->disableMipmap()); + Tile::diode_off = static_cast((new RepeaterTile(93, false))->setDestroyTime(0.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"repeater")->setDescriptionId(IDS_ITEM_DIODE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER)->disableMipmap()); Tile::diode_on = static_cast((new RepeaterTile(94, true))->setDestroyTime(0.0f)->setLightEmission(10 / 16.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"repeater_on")->setDescriptionId(IDS_ITEM_DIODE)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER)->disableMipmap()); - Tile::stained_glass = (new StainedGlassBlock(95, Material::glass))->setBaseItemTypeAndMaterial(Item::eBaseItemType_glass, Item::eMaterial_glass)->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"glass")->setDescriptionId(IDS_TILE_STAINED_GLASS)->setUseDescriptionId(IDS_DESC_STAINED_GLASS); - Tile::trapdoor = (new TrapDoorTile(96, Material::wood)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_door, Item::eMaterial_trap)->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"trapdoor")->setDescriptionId(IDS_TILE_TRAPDOOR)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_TRAPDOOR); + Tile::stained_glass = (new StainedGlassBlock(95, Material::glass))->setBaseItemTypeAndMaterial(Item::eBaseItemType_glass, Item::eMaterial_glass)->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"stained_glass")->setDescriptionId(IDS_TILE_STAINED_GLASS)->setUseDescriptionId(IDS_DESC_STAINED_GLASS); + Tile::trapdoor = (new TrapDoorTile(96, Material::wood)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_door, Item::eMaterial_trap)->setDestroyTime(3.0f)->setSoundType(Tile::SOUND_WOOD)->setIconName(L"oak_trapdoor")->setDescriptionId(IDS_TILE_TRAPDOOR)->setNotCollectStatistics()->sendTileData()->setUseDescriptionId(IDS_DESC_TRAPDOOR); Tile::monsterStoneEgg = (new StoneMonsterTile(97)) ->setDestroyTime(0.75f)->setIconName(L"monsterStoneEgg")->setDescriptionId(IDS_TILE_STONE_SILVERFISH)->setUseDescriptionId(IDS_DESC_STONE_SILVERFISH); - Tile::stoneBrick = (new SmoothStoneBrickTile(98)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_stoneSmooth)->setDestroyTime(1.5f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setIconName(L"stonebrick")->setDescriptionId(IDS_TILE_STONE_BRICK_SMOOTH)->setUseDescriptionId(IDS_DESC_STONE_BRICK_SMOOTH); + Tile::stoneBrick = (new SmoothStoneBrickTile(98)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_stoneSmooth)->setDestroyTime(1.5f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setIconName(L"stone_bricks")->setDescriptionId(IDS_TILE_STONE_BRICK_SMOOTH)->setUseDescriptionId(IDS_DESC_STONE_BRICK_SMOOTH); Tile::hugeMushroom_brown = (new HugeMushroomTile(99, Material::wood, HugeMushroomTile::MUSHROOM_TYPE_BROWN)) ->setDestroyTime(0.2f)->setSoundType(SOUND_WOOD)->setIconName(L"mushroom_block")->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_1)->setUseDescriptionId(IDS_DESC_MUSHROOM)->sendTileData(); Tile::hugeMushroom_red = (new HugeMushroomTile(100, Material::wood, HugeMushroomTile::MUSHROOM_TYPE_RED)) ->setDestroyTime(0.2f)->setSoundType(SOUND_WOOD)->setIconName(L"mushroom_block")->setDescriptionId(IDS_TILE_HUGE_MUSHROOM_2)->setUseDescriptionId(IDS_DESC_MUSHROOM)->sendTileData(); @@ -381,20 +381,20 @@ void Tile::staticCtor() Tile::stairs_stoneBrickSmooth = (new StairTile(109, Tile::stoneBrick,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_stoneSmooth)->setIconName(L"stairsStoneBrickSmooth")->setDescriptionId(IDS_TILE_STAIRS_STONE_BRICKS_SMOOTH) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::mycel = static_cast((new MycelTile(110))->setDestroyTime(0.6f)->setSoundType(SOUND_GRASS)->setIconName(L"mycelium")->setDescriptionId(IDS_TILE_MYCEL)->setUseDescriptionId(IDS_DESC_MYCEL)); - Tile::waterLily = (new WaterlilyTile(111)) ->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setIconName(L"waterlily")->setDescriptionId(IDS_TILE_WATERLILY)->setUseDescriptionId(IDS_DESC_WATERLILY); - Tile::netherBrick = (new Tile(112, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_netherbrick)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setIconName(L"nether_brick")->setDescriptionId(IDS_TILE_NETHERBRICK)->setUseDescriptionId(IDS_DESC_NETHERBRICK); - Tile::netherFence = (new FenceTile(113, L"nether_brick", Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_netherbrick)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setDescriptionId(IDS_TILE_NETHERFENCE)->setUseDescriptionId(IDS_DESC_NETHERFENCE); + Tile::waterLily = (new WaterlilyTile(111)) ->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setIconName(L"lily_pad")->setDescriptionId(IDS_TILE_WATERLILY)->setUseDescriptionId(IDS_DESC_WATERLILY); + Tile::netherBrick = (new Tile(112, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_netherbrick)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setIconName(L"nether_bricks")->setDescriptionId(IDS_TILE_NETHERBRICK)->setUseDescriptionId(IDS_DESC_NETHERBRICK); + Tile::netherFence = (new FenceTile(113, L"nether_bricks", Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fence, Item::eMaterial_netherbrick)->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setDescriptionId(IDS_TILE_NETHERFENCE)->setUseDescriptionId(IDS_DESC_NETHERFENCE); Tile::stairs_netherBricks = (new StairTile(114, Tile::netherBrick,0)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_netherbrick)->setIconName(L"stairsNetherBrick")->setDescriptionId(IDS_TILE_STAIRS_NETHERBRICK) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::netherStalk = (new NetherWartTile(115)) ->setIconName(L"nether_wart")->setDescriptionId(IDS_TILE_NETHERSTALK)->sendTileData()->setUseDescriptionId(IDS_DESC_NETHERSTALK); Tile::enchantTable = (new EnchantmentTableTile(116)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_device, Item::eMaterial_magic)->setDestroyTime(5.0f)->setExplodeable(2000)->setIconName(L"enchanting_table")->setDescriptionId(IDS_TILE_ENCHANTMENTTABLE)->setUseDescriptionId(IDS_DESC_ENCHANTMENTTABLE); Tile::brewingStand = (new BrewingStandTile(117)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_device, Item::eMaterial_blaze)->setDestroyTime(0.5f)->setLightEmission(2 / 16.0f)->setIconName(L"brewing_stand")->setDescriptionId(IDS_TILE_BREWINGSTAND)->sendTileData()->setUseDescriptionId(IDS_DESC_BREWING_STAND); Tile::cauldron = static_cast((new CauldronTile(118))->setDestroyTime(2.0f)->setIconName(L"cauldron")->setDescriptionId(IDS_TILE_CAULDRON)->sendTileData()->setUseDescriptionId(IDS_DESC_CAULDRON)); Tile::endPortalTile = (new TheEndPortal(119, Material::portal)) ->setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME)->setExplodeable(6000000)->setDescriptionId(IDS_TILE_END_PORTAL)->setUseDescriptionId(IDS_DESC_END_PORTAL); - Tile::endPortalFrameTile = (new TheEndPortalFrameTile(120)) ->setSoundType(SOUND_GLASS)->setLightEmission(2 / 16.0f)->setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME)->setIconName(L"endframe")->setDescriptionId(IDS_TILE_ENDPORTALFRAME)->sendTileData()->setExplodeable(6000000)->setUseDescriptionId(IDS_DESC_ENDPORTALFRAME); + Tile::endPortalFrameTile = (new TheEndPortalFrameTile(120)) ->setSoundType(SOUND_GLASS)->setLightEmission(2 / 16.0f)->setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME)->setIconName(L"end_portal_frame")->setDescriptionId(IDS_TILE_ENDPORTALFRAME)->sendTileData()->setExplodeable(6000000)->setUseDescriptionId(IDS_DESC_ENDPORTALFRAME); Tile::endStone = (new Tile(121, Material::stone)) ->setDestroyTime(3.0f)->setExplodeable(15)->setSoundType(SOUND_STONE)->setIconName(L"end_stone")->setDescriptionId(IDS_TILE_WHITESTONE)->setUseDescriptionId(IDS_DESC_WHITESTONE); Tile::dragonEgg = (new EggTile(122)) ->setDestroyTime(3.0f)->setExplodeable(15)->setSoundType(SOUND_STONE)->setLightEmission(2.0f / 16.0f)->setIconName(L"dragon_egg")->setDescriptionId(IDS_TILE_DRAGONEGG)->setUseDescriptionId(IDS_DESC_DRAGONEGG); - Tile::redstoneLight = (new RedlightTile(123, false)) ->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"redstone_lamp_off")->setDescriptionId(IDS_TILE_REDSTONE_LIGHT)->setUseDescriptionId(IDS_DESC_REDSTONE_LIGHT); + Tile::redstoneLight = (new RedlightTile(123, false)) ->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"redstone_lamp")->setDescriptionId(IDS_TILE_REDSTONE_LIGHT)->setUseDescriptionId(IDS_DESC_REDSTONE_LIGHT); Tile::redstoneLight_lit = (new RedlightTile(124, true)) ->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"redstone_lamp_on")->setDescriptionId(IDS_TILE_REDSTONE_LIGHT)->setUseDescriptionId(IDS_DESC_REDSTONE_LIGHT); Tile::woodSlab = static_cast((new WoodSlabTile(Tile::woodSlab_Id, true))->setBaseItemTypeAndMaterial(Item::eBaseItemType_slab, Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB)); Tile::woodSlabHalf = static_cast((new WoodSlabTile(Tile::woodSlabHalf_Id, false))->setBaseItemTypeAndMaterial(Item::eBaseItemType_halfslab, Item::eMaterial_wood)->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB)); @@ -404,8 +404,8 @@ void Tile::staticCtor() Tile::enderChest = (new EnderChestTile(130)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_chest, Item::eMaterial_ender)->setDestroyTime(22.5f)->setExplodeable(1000)->setSoundType(SOUND_STONE)->setIconName(L"enderChest")->sendTileData()->setLightEmission(.5f)->setDescriptionId(IDS_TILE_ENDERCHEST)->setUseDescriptionId(IDS_DESC_ENDERCHEST); - Tile::tripWireSource = static_cast((new TripWireSourceTile(131))->setBaseItemTypeAndMaterial(Item::eBaseItemType_lever, Item::eMaterial_undefined)->setIconName(L"trip_wire_source")->sendTileData()->setDescriptionId(IDS_TILE_TRIPWIRE_SOURCE)->setUseDescriptionId(IDS_DESC_TRIPWIRE_SOURCE)); - Tile::tripWire = (new TripWireTile(132)) ->setIconName(L"trip_wire")->sendTileData()->setDescriptionId(IDS_TILE_TRIPWIRE)->setUseDescriptionId(IDS_DESC_TRIPWIRE); + Tile::tripWireSource = static_cast((new TripWireSourceTile(131))->setBaseItemTypeAndMaterial(Item::eBaseItemType_lever, Item::eMaterial_undefined)->setIconName(L"tripwire_hook")->sendTileData()->setDescriptionId(IDS_TILE_TRIPWIRE_SOURCE)->setUseDescriptionId(IDS_DESC_TRIPWIRE_SOURCE)); + Tile::tripWire = (new TripWireTile(132)) ->setIconName(L"tripwire")->sendTileData()->setDescriptionId(IDS_TILE_TRIPWIRE)->setUseDescriptionId(IDS_DESC_TRIPWIRE); Tile::emeraldBlock = (new MetalTile(133)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_emerald)->setDestroyTime(5.0f)->setExplodeable(10)->setSoundType(SOUND_METAL)->setIconName(L"emerald_block")->setDescriptionId(IDS_TILE_EMERALDBLOCK)->setUseDescriptionId(IDS_DESC_EMERALDBLOCK); Tile::woodStairsDark = (new StairTile(134, Tile::wood, TreeTile::DARK_TRUNK)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_sprucewood)->setIconName(L"stairsWoodSpruce")->setDescriptionId(IDS_TILE_STAIRS_SPRUCEWOOD) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); Tile::woodStairsBirch = (new StairTile(135, Tile::wood, TreeTile::BIRCH_TRUNK)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_birchwood)->setIconName(L"stairsWoodBirch")->setDescriptionId(IDS_TILE_STAIRS_BIRCHWOOD) ->sendTileData()->setUseDescriptionId(IDS_DESC_STAIRS); @@ -423,31 +423,31 @@ void Tile::staticCtor() Tile::chest_trap = (new ChestTile(146, ChestTile::TYPE_TRAP)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_chest, Item::eMaterial_trap)->setDestroyTime(2.5f)->setSoundType(SOUND_WOOD)->setDescriptionId(IDS_TILE_CHEST_TRAP)->setUseDescriptionId(IDS_DESC_CHEST_TRAP); Tile::weightedPlate_light = (new WeightedPressurePlateTile(147, L"gold_block", Material::metal, Redstone::SIGNAL_MAX)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_gold)->setDestroyTime(0.5f)->setSoundType(SOUND_WOOD)->setDescriptionId(IDS_TILE_WEIGHTED_PLATE_LIGHT)->setUseDescriptionId(IDS_DESC_WEIGHTED_PLATE_LIGHT); Tile::weightedPlate_heavy = (new WeightedPressurePlateTile(148, L"iron_block", Material::metal, Redstone::SIGNAL_MAX * 10))->setBaseItemTypeAndMaterial(Item::eBaseItemType_pressureplate, Item::eMaterial_iron)->setDestroyTime(0.5f)->setSoundType(SOUND_WOOD)->setDescriptionId(IDS_TILE_WEIGHTED_PLATE_HEAVY)->setUseDescriptionId(IDS_DESC_WEIGHTED_PLATE_HEAVY); - Tile::comparator_off = static_cast((new ComparatorTile(149, false))->setDestroyTime(0.0f)->setSoundType(SOUND_WOOD)->setIconName(L"comparator_off")->setDescriptionId(IDS_TILE_COMPARATOR)->setUseDescriptionId(IDS_DESC_COMPARATOR)); + Tile::comparator_off = static_cast((new ComparatorTile(149, false))->setDestroyTime(0.0f)->setSoundType(SOUND_WOOD)->setIconName(L"comparator")->setDescriptionId(IDS_TILE_COMPARATOR)->setUseDescriptionId(IDS_DESC_COMPARATOR)); Tile::comparator_on = static_cast((new ComparatorTile(150, true))->setDestroyTime(0.0f)->setLightEmission(10 / 16.0f)->setSoundType(SOUND_WOOD)->setIconName(L"comparator_on")->setDescriptionId(IDS_TILE_COMPARATOR)->setUseDescriptionId(IDS_DESC_COMPARATOR)); Tile::daylightDetector = static_cast((new DaylightDetectorTile(151))->setDestroyTime(0.2f)->setSoundType(SOUND_WOOD)->setIconName(L"daylight_detector")->setDescriptionId(IDS_TILE_DAYLIGHT_DETECTOR)->setUseDescriptionId(IDS_DESC_DAYLIGHT_DETECTOR)); Tile::redstoneBlock = (new PoweredMetalTile(152)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_redstone)->setDestroyTime(5.0f)->setExplodeable(10)->setSoundType(SOUND_METAL)->setIconName(L"redstone_block")->setDescriptionId(IDS_TILE_REDSTONE_BLOCK)->setUseDescriptionId(IDS_DESC_REDSTONE_BLOCK); - Tile::netherQuartz = (new OreTile(153)) ->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setIconName(L"quartz_ore")->setDescriptionId(IDS_TILE_NETHER_QUARTZ)->setUseDescriptionId(IDS_DESC_NETHER_QUARTZ_ORE); + Tile::netherQuartz = (new OreTile(153)) ->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setIconName(L"nether_quartz_ore")->setDescriptionId(IDS_TILE_NETHER_QUARTZ)->setUseDescriptionId(IDS_DESC_NETHER_QUARTZ_ORE); Tile::hopper = static_cast((new HopperTile(154))->setBaseItemTypeAndMaterial(Item::eBaseItemType_redstoneContainer, Item::eMaterial_undefined)->setDestroyTime(3.0f)->setExplodeable(8)->setSoundType(SOUND_WOOD)->setIconName(L"hopper")->setDescriptionId(IDS_TILE_HOPPER)->setUseDescriptionId(IDS_DESC_HOPPER)); Tile::quartzBlock = (new QuartzBlockTile(155)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_structblock, Item::eMaterial_quartz)->setSoundType(SOUND_STONE)->setDestroyTime(0.8f)->setIconName(L"quartz_block")->setDescriptionId(IDS_TILE_QUARTZ_BLOCK)->setUseDescriptionId(IDS_DESC_QUARTZ_BLOCK); Tile::stairs_quartz = (new StairTile(156, Tile::quartzBlock, QuartzBlockTile::TYPE_DEFAULT)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_stairs, Item::eMaterial_quartz)->setIconName(L"stairsQuartz")->setDescriptionId(IDS_TILE_STAIRS_QUARTZ)->setUseDescriptionId(IDS_DESC_STAIRS); - Tile::activatorRail = (new PoweredRailTile(157)) ->setDestroyTime(0.7f)->setSoundType(SOUND_METAL)->setIconName(L"rail_activator")->setDescriptionId(IDS_TILE_ACTIVATOR_RAIL)->setUseDescriptionId(IDS_DESC_ACTIVATOR_RAIL); + Tile::activatorRail = (new PoweredRailTile(157)) ->setDestroyTime(0.7f)->setSoundType(SOUND_METAL)->setIconName(L"activator_rail")->setDescriptionId(IDS_TILE_ACTIVATOR_RAIL)->setUseDescriptionId(IDS_DESC_ACTIVATOR_RAIL); Tile::dropper = (new DropperTile(158)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_redstoneContainer, Item::eMaterial_undefined)->setDestroyTime(3.5f)->setSoundType(SOUND_STONE)->setIconName(L"dropper")->setDescriptionId(IDS_TILE_DROPPER)->setUseDescriptionId(IDS_DESC_DROPPER); - Tile::clayHardened_colored = (new ColoredTile(159, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_clay, Item::eMaterial_clay)->setDestroyTime(1.25f)->setExplodeable(7)->setSoundType(SOUND_STONE)->setIconName(L"hardened_clay_stained")->setDescriptionId(IDS_TILE_STAINED_CLAY)->setUseDescriptionId(IDS_DESC_STAINED_CLAY); - Tile::stained_glass_pane = (new StainedGlassPaneBlock(160)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_glass, Item::eMaterial_glass)->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"glass")->setDescriptionId(IDS_TILE_STAINED_GLASS_PANE)->setUseDescriptionId(IDS_DESC_STAINED_GLASS_PANE); + Tile::clayHardened_colored = (new ColoredTile(159, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_clay, Item::eMaterial_clay)->setDestroyTime(1.25f)->setExplodeable(7)->setSoundType(SOUND_STONE)->setIconName(L"terracotta")->setDescriptionId(IDS_TILE_STAINED_CLAY)->setUseDescriptionId(IDS_DESC_STAINED_CLAY); + Tile::stained_glass_pane = (new StainedGlassPaneBlock(160)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_glass, Item::eMaterial_glass)->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setIconName(L"stained_glass")->setDescriptionId(IDS_TILE_STAINED_GLASS_PANE)->setUseDescriptionId(IDS_DESC_STAINED_GLASS_PANE); Tile::hayBlock = (new HayBlockTile(170)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_wheat)->setDestroyTime(0.5f)->setSoundType(SOUND_GRASS)->setIconName(L"hay_block")->setDescriptionId(IDS_TILE_HAY)->setUseDescriptionId(IDS_DESC_HAY); Tile::woolCarpet = (new WoolCarpetTile(171)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_carpet, Item::eMaterial_cloth)->setDestroyTime(0.1f)->setSoundType(SOUND_CLOTH)->setIconName(L"woolCarpet")->setLightBlock(0)->setDescriptionId(IDS_TILE_CARPET)->setUseDescriptionId(IDS_DESC_CARPET); - Tile::clayHardened = (new Tile(172, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_clay, Item::eMaterial_clay)->setDestroyTime(1.25f)->setExplodeable(7)->setSoundType(SOUND_STONE)->setIconName(L"hardened_clay")->setDescriptionId(IDS_TILE_HARDENED_CLAY)->setUseDescriptionId(IDS_DESC_HARDENED_CLAY); + Tile::clayHardened = (new Tile(172, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_clay, Item::eMaterial_clay)->setDestroyTime(1.25f)->setExplodeable(7)->setSoundType(SOUND_STONE)->setIconName(L"terracotta")->setDescriptionId(IDS_TILE_HARDENED_CLAY)->setUseDescriptionId(IDS_DESC_HARDENED_CLAY); Tile::coalBlock = (new Tile(173, Material::stone)) ->setBaseItemTypeAndMaterial(Item::eBaseItemType_block, Item::eMaterial_coal)->setDestroyTime(5.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setIconName(L"coal_block")->setDescriptionId(IDS_TILE_COAL)->setUseDescriptionId(IDS_DESC_COAL_BLOCK); // Special cases for certain items since they can have different icons Item::items[wool_Id] = ( new WoolTileItem(Tile::wool_Id- 256) )->setIconName(L"cloth")->setDescriptionId(IDS_TILE_CLOTH)->setUseDescriptionId(IDS_DESC_WOOL); Item::items[clayHardened_colored_Id]= ( new WoolTileItem(Tile::clayHardened_colored_Id - 256))->setIconName(L"clayHardenedStained")->setDescriptionId(IDS_TILE_STAINED_CLAY)->setUseDescriptionId(IDS_DESC_STAINED_CLAY); - Item::items[stained_glass_Id] = ( new WoolTileItem(Tile::stained_glass_Id - 256))->setIconName(L"stainedGlass")->setDescriptionId(IDS_TILE_STAINED_GLASS)->setUseDescriptionId(IDS_DESC_STAINED_GLASS); - Item::items[stained_glass_pane_Id] = ( new WoolTileItem(Tile::stained_glass_pane_Id - 256))->setIconName(L"stainedGlassPane")->setDescriptionId(IDS_TILE_STAINED_GLASS_PANE)->setUseDescriptionId(IDS_DESC_STAINED_GLASS_PANE); + Item::items[stained_glass_Id] = ( new WoolTileItem(Tile::stained_glass_Id - 256))->setIconName(L"stained_glass")->setDescriptionId(IDS_TILE_STAINED_GLASS)->setUseDescriptionId(IDS_DESC_STAINED_GLASS); + Item::items[stained_glass_pane_Id] = ( new WoolTileItem(Tile::stained_glass_pane_Id - 256))->setIconName(L"stained_glass_pane")->setDescriptionId(IDS_TILE_STAINED_GLASS_PANE)->setUseDescriptionId(IDS_DESC_STAINED_GLASS_PANE); Item::items[woolCarpet_Id] = ( new WoolTileItem(Tile::woolCarpet_Id - 256))->setIconName(L"woolCarpet")->setDescriptionId(IDS_TILE_CARPET)->setUseDescriptionId(IDS_DESC_CARPET); Item::items[treeTrunk_Id] = ( new MultiTextureTileItem(Tile::treeTrunk_Id - 256, treeTrunk, (int *)TreeTile::TREE_NAMES, 4) )->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->setUseDescriptionId(IDS_DESC_LOG); Item::items[wood_Id] = ( new MultiTextureTileItem(Tile::wood_Id - 256, Tile::wood, (int *)WoodTile::WOOD_NAMES, 4, IDS_TILE_PLANKS))->setIconName(L"wood")->setDescriptionId(IDS_TILE_OAKWOOD_PLANKS)->setUseDescriptionId(IDS_DESC_LOG); // <- TODO @@ -455,8 +455,8 @@ void Tile::staticCtor() Item::items[stoneBrick_Id] = ( new MultiTextureTileItem(Tile::stoneBrick_Id - 256, stoneBrick,(int *)SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES, 4))->setIconName(L"stonebricksmooth")->setDescriptionId(IDS_TILE_STONE_BRICK_SMOOTH); Item::items[sandStone_Id] = ( new MultiTextureTileItem(sandStone_Id - 256, sandStone, SandStoneTile::SANDSTONE_NAMES, SandStoneTile::SANDSTONE_BLOCK_NAMES) )->setIconName(L"sandStone")->setDescriptionId(IDS_TILE_SANDSTONE)->setUseDescriptionId(IDS_DESC_SANDSTONE); Item::items[quartzBlock_Id] = ( new MultiTextureTileItem(quartzBlock_Id - 256, quartzBlock, QuartzBlockTile::BLOCK_NAMES, QuartzBlockTile::QUARTZ_BLOCK_NAMES) )->setIconName(L"quartzBlock")->setDescriptionId(IDS_TILE_QUARTZ_BLOCK)->setUseDescriptionId(IDS_DESC_QUARTZ_BLOCK); - Item::items[stoneSlabHalf_Id] = ( new StoneSlabTileItem(Tile::stoneSlabHalf_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, false) )->setIconName(L"stoneSlab")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_HALFSLAB); - Item::items[stoneSlab_Id] = ( new StoneSlabTileItem(Tile::stoneSlab_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, true))->setIconName(L"stoneSlab")->setDescriptionId(IDS_DESC_STONESLAB)->setUseDescriptionId(IDS_DESC_SLAB); + Item::items[stoneSlabHalf_Id] = ( new StoneSlabTileItem(Tile::stoneSlabHalf_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, false) )->setIconName(L"smooth_stone")->setDescriptionId(IDS_TILE_STONESLAB)->setUseDescriptionId(IDS_DESC_HALFSLAB); + Item::items[stoneSlab_Id] = ( new StoneSlabTileItem(Tile::stoneSlab_Id - 256, Tile::stoneSlabHalf, Tile::stoneSlab, true))->setIconName(L"smooth_stone")->setDescriptionId(IDS_DESC_STONESLAB)->setUseDescriptionId(IDS_DESC_SLAB); Item::items[woodSlabHalf_Id] = ( new StoneSlabTileItem(Tile::woodSlabHalf_Id - 256, Tile::woodSlabHalf, Tile::woodSlab, false))->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB); Item::items[woodSlab_Id] = ( new StoneSlabTileItem(Tile::woodSlab_Id - 256, Tile::woodSlabHalf, Tile::woodSlab, true))->setIconName(L"woodSlab")->setDescriptionId(IDS_DESC_WOODSLAB)->setUseDescriptionId(IDS_DESC_WOODSLAB); Item::items[sapling_Id] = ( new MultiTextureTileItem(Tile::sapling_Id - 256, Tile::sapling, Sapling::SAPLING_NAMES, 4) )->setIconName(L"sapling")->setDescriptionId(IDS_TILE_SAPLING)->setUseDescriptionId(IDS_DESC_SAPLING); diff --git a/Minecraft.World/Tile.h b/Minecraft.World/Tile.h index 307c4106a9..0bcdf926e8 100644 --- a/Minecraft.World/Tile.h +++ b/Minecraft.World/Tile.h @@ -715,9 +715,9 @@ class Tile protected: virtual Tile *setIconName(const wstring &iconName); - virtual wstring getIconName(); public: + virtual wstring getIconName(); virtual void registerIcons(IconRegister *iconRegister); virtual wstring getTileItemIconName(); diff --git a/Minecraft.World/TreeTile.cpp b/Minecraft.World/TreeTile.cpp index 6a5860f3ae..f1e795e04b 100644 --- a/Minecraft.World/TreeTile.cpp +++ b/Minecraft.World/TreeTile.cpp @@ -88,7 +88,7 @@ void TreeTile::registerIcons(IconRegister *iconRegister) { for (int i = 0; i < TREE_NAMES_LENGTH; i++) { - icons_side[i] = iconRegister->registerIcon(getIconName() + L"_" + TREE_STRING_NAMES[i]); - icons_top[i] = iconRegister->registerIcon(getIconName() + L"_" + TREE_STRING_NAMES[i] + L"_top"); + icons_side[i] = iconRegister->registerIcon(TREE_STRING_NAMES[i] + L"_" + getIconName()); + icons_top[i] = iconRegister->registerIcon(TREE_STRING_NAMES[i] + L"_" + getIconName() + L"_top"); } } \ No newline at end of file diff --git a/Minecraft.World/WoodTile.cpp b/Minecraft.World/WoodTile.cpp index 239ef61c4e..71b2947fbb 100644 --- a/Minecraft.World/WoodTile.cpp +++ b/Minecraft.World/WoodTile.cpp @@ -51,6 +51,6 @@ void WoodTile::registerIcons(IconRegister *iconRegister) for (int i = 0; i < WOOD_NAMES_LENGTH; i++) { - icons[i] = iconRegister->registerIcon(getIconName() + L"_" + TEXTURE_NAMES[i]); + icons[i] = iconRegister->registerIcon(TEXTURE_NAMES[i] + L"_" + getIconName()); } } \ No newline at end of file diff --git a/Minecraft.World/WorkbenchTile.cpp b/Minecraft.World/WorkbenchTile.cpp index cc505fc6a9..7cfb839dbd 100644 --- a/Minecraft.World/WorkbenchTile.cpp +++ b/Minecraft.World/WorkbenchTile.cpp @@ -21,9 +21,9 @@ Icon *WorkbenchTile::getTexture(int face, int data) void WorkbenchTile::registerIcons(IconRegister *iconRegister) { - icon = iconRegister->registerIcon(L"workbench_side"); - iconTop = iconRegister->registerIcon(L"workbench_top"); - iconFront = iconRegister->registerIcon(L"workbench_front"); + icon = iconRegister->registerIcon(getIconName() + L"_side"); + iconTop = iconRegister->registerIcon(getIconName() + L"_top"); + iconFront = iconRegister->registerIcon(getIconName() + L"_front"); } // 4J-PB - Adding a TestUse for tooltip display diff --git a/Minecraft.World/ZipEntry.cpp b/Minecraft.World/ZipEntry.cpp new file mode 100644 index 0000000000..7765d45c8d --- /dev/null +++ b/Minecraft.World/ZipEntry.cpp @@ -0,0 +1,27 @@ +#include "stdafx.h" +#include "ZipEntry.h" + +ZipEntry::ZipEntry(bit7z::BitArchiveItemOffset itemInfo) : _itemInfo(itemInfo) { + _name = itemInfo.name(); + _path = itemInfo.path(); +} + +DWORD ZipEntry::getSize() { + return _itemInfo.size(); +} + +bool ZipEntry::isDir() { + return _itemInfo.isDir(); +} + +std::string ZipEntry::getName() { + return _name; +} + +std::string ZipEntry::path() { + return _path; +} + +unsigned int ZipEntry::getIndex() { + return (unsigned int)_itemInfo.index(); +} \ No newline at end of file diff --git a/Minecraft.World/ZipEntry.h b/Minecraft.World/ZipEntry.h new file mode 100644 index 0000000000..12eeb2023c --- /dev/null +++ b/Minecraft.World/ZipEntry.h @@ -0,0 +1,20 @@ +#pragma once +#include "../Minecraft.Client/Common/libs/bit7z/include/bitarchivereader.hpp" + +class ZipEntry { +private: + bit7z::BitArchiveItemOffset _itemInfo; + + // caching for faster load times + std::string _name; + std::string _path; + +public: + ZipEntry(bit7z::BitArchiveItemOffset itemInfo); + DWORD getSize(); + bool isDir(); + bool isFile() { return !isDir(); } + std::string getName(); + std::string path(); + unsigned int getIndex(); +}; \ No newline at end of file diff --git a/Minecraft.World/ZipFile.cpp b/Minecraft.World/ZipFile.cpp new file mode 100644 index 0000000000..1ab8d226b1 --- /dev/null +++ b/Minecraft.World/ZipFile.cpp @@ -0,0 +1,140 @@ +#include "stdafx.h" +#include "ZipFile.h" + +// static library +bit7z::Bit7zLibrary* ZipFile::_library; + +ZipFile::ZipFile(File* file) { + if (file != NULL && file->exists()) { + open(file); + } +} + +ZipFile::ZipFile(std::string name) { + File file(convStringToWstring(name)); + if (file.exists()) { + open(&file); + } +} + +std::vector ZipFile::listFiles() { + std::vector files; + files.reserve(_fileCache.size()); + + for (auto item : _fileCache) { + files.emplace_back(item.first); + } + return files; +} + +// returns -1 if not found +std::unique_ptr ZipFile::getEntry(const std::wstring* name) { + bool path = name->find('/') != name->npos || name->find('\\') != name->npos; + std::wstring nameCopy = *name; +#ifdef _WIN64 + if (path) { // + for (int i = 0; i < nameCopy.length(); i++) + if (nameCopy[i] == L'/') + nameCopy[i] = L'\\'; + } +#endif + + auto it = _fileCache.find(nameCopy); + if (it != _fileCache.end()) { + auto entryInfo = _reader->itemAt(it->second); + return std::make_unique(entryInfo); + } + + return nullptr; +} + +std::vector ZipFile::extract(const std::wstring* name) { + auto entry = getEntry(name); + if (!entry) + return {}; + + try { + auto size = entry->getSize(); + std::vector buffer(size); + _reader->extractTo(buffer.data(), size, entry->getIndex()); + return buffer; + } + catch (exception e) { + app.DebugPrintf(wstringtostring(L"Error extracting file from zip: " + *name + L'\n').c_str()); + app.DebugPrintf(wstringtostring(L"Exception: " + convStringToWstring(e.what()) + L'\n').c_str()); + __debugbreak(); + return {}; + } +} + +bool ZipFile::hasFile(const std::wstring* name) { + bool path = name->find('/') != name->npos || name->find('\\') != name->npos; + std::wstring nameCopy = *name; +#ifdef _WIN64 + if (path) { // + for (int i = 0; i < nameCopy.length(); i++) + if (nameCopy[i] == L'/') + nameCopy[i] = L'\\'; + } +#endif + + return _fileCache.find(nameCopy) != _fileCache.end(); +} + +bool ZipFile::hasFile(char* str) { + try { + std::wstring wstr = convStringToWstring(std::string(str)); + return hasFile(&wstr); + } + catch (exception e) { + return false; + } +} + +InputStream* ZipFile::getInputStream(ZipEntry* entry) { + std::vector data(entry->getSize()); + _reader->extractTo(data.data(), data.size(), entry->getIndex()); + byteArray* buf = new byteArray(data.data(), data.size()); + ByteArrayInputStream* stream = new ByteArrayInputStream(*buf, 0, data.size()); + return stream; +} + +InputStream* ZipFile::getInputStream(int entryId) { + auto entry = _reader->itemAt(entryId); + std::vector data(entry.size()); + _reader->extractTo(data.data(), data.size(), entry.index()); + byteArray* buf = new byteArray(data.data(), data.size()); + ByteArrayInputStream* stream = new ByteArrayInputStream(*buf, 0, data.size()); + return stream; +} + +bool ZipFile::open(File* file) { + try { + std::wstring wpath = file->getPath(); + int charCount = WideCharToMultiByte(CP_UTF8, 0, wpath.c_str(), -1, NULL, 0, NULL, NULL); + std::string path(charCount - 1, 0); + WideCharToMultiByte(CP_UTF8, 0, wpath.c_str(), -1, &path[0], charCount, NULL, NULL); + + if (_library == nullptr) { + OutputDebugString("Initializing bit7z library"); + _library = new bit7z::Bit7zLibrary("Windows64Media\\7z.dll"); + } + + _reader = std::make_unique(*_library, path, bit7z::BitFormat::Zip); + auto _libentries = _reader->items(); + _fileCache.clear(); + + for (auto &item : _libentries) { + if (!item.isDir()) { // We never unpack directories, this also saves time comparing against them + _fileCache[item.nativePath()] = item.index(); + _fileCache[convStringToWstring(item.name())] = item.index(); + } + } + } + catch (exception e) { + app.DebugPrintf(wstringtostring(L"Error opening zip file: " + file->getPath()).c_str()); + app.DebugPrintf(wstringtostring(L"\nException: " + convStringToWstring(e.what())).c_str()); + __debugbreak(); + } + return false; +} \ No newline at end of file diff --git a/Minecraft.World/ZipFile.h b/Minecraft.World/ZipFile.h new file mode 100644 index 0000000000..a359a472d0 --- /dev/null +++ b/Minecraft.World/ZipFile.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include +#include "File.h" +#include "ZipEntry.h" +#include "../Minecraft.Client/Common/libs/bit7z/include/bitarchivereader.hpp" + +class ZipFile { +public: + ZipFile(File* file); + ZipFile(std::string name); + std::vector listFiles(); + bool hasFile(const std::wstring* name); + bool hasFile(char* str); + std::unique_ptr getEntry(const std::wstring* name); + std::vector extract(const std::wstring* name); + InputStream* getInputStream(ZipEntry* entry); + InputStream* getInputStream(int entryId); + + +private: + static bit7z::Bit7zLibrary* _library; + std::unique_ptr _reader; + unordered_map _fileCache; + + + bool open(File* file); + + +}; \ No newline at end of file diff --git a/Minecraft.World/cmake/sources/Common.cmake b/Minecraft.World/cmake/sources/Common.cmake index 8a4d683303..1f91e78e58 100644 --- a/Minecraft.World/cmake/sources/Common.cmake +++ b/Minecraft.World/cmake/sources/Common.cmake @@ -69,6 +69,10 @@ set(_MINECRAFT_WORLD_COMMON_CONSOLEJAVALIBS "${CMAKE_CURRENT_SOURCE_DIR}/SocketAddress.h" "${CMAKE_CURRENT_SOURCE_DIR}/System.h" "${CMAKE_CURRENT_SOURCE_DIR}/system.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/ZipFile.h" + "${CMAKE_CURRENT_SOURCE_DIR}/ZipFile.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/ZipEntry.h" + "${CMAKE_CURRENT_SOURCE_DIR}/ZipEntry.cpp" ) source_group("ConsoleJavaLibs" FILES ${_MINECRAFT_WORLD_COMMON_CONSOLEJAVALIBS})