Giter Site home page Giter Site logo

warframe-exporter's Introduction

Warframe Extractor

A cross-platform program/library for exporting files from Warframe. Provides a Command-line and Graphical interface. "Easily" extensible to support new formats and upgrades to existing formats.


Preview

How to use

Download the latest release.

  • Warframe-Exporter is the easy-to-use program with a Graphical User Interface.
  • Warframe-Exporter-CLI is a Command-Line interface. This is useful for writing scripts to export files.
  • Warframe-Exporter-CLI-Advanced is a Command-Line interface with extra features. You probably don't need this unless you're familiar with the inner workings of Warframe.

External Libraries

ImHex Patterns

Inside the utils folder, you'll find a collection of .hexpat files. These are patterns for ImHex. If you're interested in the file formats analyzed in this repo, I highly recommend using these.

  1. Download and install ImHex
  2. Copy all .hexpat files into C:\Users\<Username>\AppData\Local\imhex\patterns or ~/.local/share/imhex/patterns
  3. Load a raw file into Imhex for analysis
    1. Using the advanced tool, find specific formats using the --print-enums flag
    2. Write raw files from the advanced tool using the --write-raw flag
  4. Within ImHex, go to File -> Import -> Pattern File and select the appropriate pattern

Contributions

Adding New Extractor

If you indend to add a new format such as Animation, Maps, Audio, etc.

  1. Create a new branch (if it doesn't already exist).
  2. Create a new folder in include and src. Store all subsequent files in here.
  3. Create a new class that inherits from the Extractor class (in Extractor.h).
  4. Register the class inside EnumMapExtractor.h.
  5. Add documentation to the README
    1. Add instructions to "Contributions"
    2. Add the format to "Formats currently supported"
  6. Add the CLI commands (Yes, I know it's a pain. At least it's documented!)
    1. Debug
      1. Add the new SwitchArg command in CLI-Debug.h
      2. Initilize that member variable in the constructor inside CLI-Debug.cpp
      3. Add that member variable to the CLI inside addMainCmds
      4. Add the member variable check to the if statement inside processCmd AND debug
      5. Add a package name to getPkgsNames
    2. Extract
      1. Add the new SwitchArg command in CLI-Extract.h
      2. Initilize that member variable in the constructor inside CLI-Extract.cpp
      3. Add that member variable to the CLI inside addMainCmds
      4. Add the member variable check to the if statement inside addMiscCommands AND processCmd
      5. Add a package name to getPkgsNames
  7. Add the UI features
    1. Add UI Buttons
      1. Download and open Qt6 Designer
      2. Open Picker.ui
      3. Add Checkboxes to an appropriate location
      4. Update the checkbox names in the "Object Inspector" window on Designer
    2. Add checkbox value to pickerDone signal
      1. Open src/ui/UIPicker.cpp
      2. Inside the function parsePickerOptions, add if statements for both checkboxes
    3. Add load/save settings
      1. Inside include/ui/Settings.h, add static const QString values for view/export
      2. Inside include/ui/Settings.h, Add getter-methods for view/export
      3. Implement above methods inside src/ui/Settings.cpp
      4. Add save commands inside src/ui/Settings.cpp method setSettings
      5. Add calls to these functions inside src/ui/UIPicker.cpp method loadSettings
    4. Add new package loads
      1. If needed, add new package loading to src/ui/UIExporter.cpp method getPackageNames

Adding a new 3D Model/Texture/Material/etc type

Warframe will often add slightly altered file formats. You can tell by the new enumeration value inside the CommonHeader. New formats need manual inspection and addition to the extractor. You can see all the existing file foramts inside each respective asset type's folder named types.

<type> refers to the asset type. Ex: model, texture, etc.

  1. Add the new enum value inside <type>Types.h
  2. Add the enum value to getEnumMapKeys() (inside <type>Extractor.h)
  3. Add a new reader class in the directory types. You should copy an existing class - the new format will likely be very similar to a previous one.
  4. Register the class to g_enumMap<type> (inside <type>EnumMap.h)

Adding a new Texture Compression Format

This is very unlikely to occur. They recently started using BC6 and BC7, so there's no more compression formats they could use. Unless they add another uncompressed format.

  1. Add the new enum value to WarframeExporter::Texture::TextureCompression (inside texture/TextureInfo.h)
  2. Add a new class inside texture/TextureInfos.h.
  3. Register the new class to WarframeExporter::Texture::g_enumMapTexture (inside texture/TextureEnumMap.h)

Building

CMake is very nice and I love it. See how easy this is to compile? I hate GUIs and Windows.

Requirements

  • Packages
    • Windows: CMake, git, Visual Studio 2022
    • Other OSs: CMake, git, any C++ compiler
  • A copy of the Oodle SDK (Provided by Unreal Engine)
    • Download the files.
      • Easy: Download from here.
      • Hard: Download from the engine
        • Download Unreal Engine from the official website (You will need an account and the Epic launcher)
        • Once downloaded find the SDK folder Engine/Source/Runtime/OodleDataCompression/Sdks/2.9.5/lib
    • Create a folder in the root of this repository named bin
    • Copy folders Linux and Win64 into bin. We want the static libraries here.

Build Commands

  1. git clone https://github.com/Puxtril/Warframe-Exporter.git && cd Warframe-Exporter
  2. Edit the first few lines of CMakeLists.txt to build what you want.
  3. Initilize the submodules
    1. cd lib
    2. git submodule update --init Binary-Reader ddspp fx-gltf glm json LotusLib spdlog tclap-code
  4. If you're on Windows and haven't installed the Qt6 SDK
    1. Initilize the repositories
      1. git submodule update --init qt5
      2. cd qt5
      3. git submodule update --init qtbase qttools qtdeclarative
      4. cd qttools
      5. git submodule update --init
      6. cd ../../..
    2. Build Qt
      1. mkdir build-qt && cd build-qt
      2. Run the rest of these commands from the MSVC shell (x64 Native Tools Command Prompt)
      3. ../lib/qt5/configure -release -optimize-size -prefix "../lib/qt-install" -confirm-license
      4. cmake --build . --parallel 4
      5. cmake --install .
  5. Install zlib
    1. Linux: Install using your package manager.
    2. Windows: sigh follow these steps.
      1. cd into an empty directory. We will build zlib here.
      2. git clone https://github.com/madler/zlib.git
      3. mkdir zlib-build
      4. cd zlib-build
      5. cmake ..\zlib -DCMAKE_INSTALL_PREFIX=..\zlib-install
      6. cmake --build . --config Release
      7. cmake --install .
  6. Build Warframe-Exporter
    1. mkdir build && cd build
    2. Linux: cmake .. Windows: cmake .. -DZLIB_ROOT=<path-to>/zlib-build
    3. Linux: make Windows: cmake --build . --config Release
  7. Copy dependencies (Windows)
    1. ../lib/qt-install/bin/windeployqt Warframe-Exporter.exe

Overview of this library

For more information on the cache file structure, read the LotusLib documentation.

High-level overview

Inside the Cache files Warframe stores on your computer (.toc and .cache), lie all the game's assets. The assets are not stored in standard formats like PNG images or FBX 3D models, they're stored in custom formats. This program reads these custom assets from the cache and converts them into sandard formats. Since it's only reading files from the cache, there is 0 risk of being banned from Warframe. Unless you run this while Warframe is running, then Warframe may detect something is reading the cache files.

Low-level overview

Every virtual file inside the cache contains a Common Header structure. Inside this structure is an integer enumeration indicating the file type. This file type dictates the structure of data following the Common Header. This Extractor maintains a list of all the supported file type eumerations depending on which category it falls into (Ex. Model enumerations are inside the model folder, textures inside the texture folder, etc).

I've implemented my own flow to extract assets. The goal was to ensure new formats can easily be added (which has been proved true). Each folder (ex. Model, Texture, Material, etc) implements this basic structure:

  1. Read the virtual file into an external data structure. The external structure should resemble the source file structure as closely as possible.
  2. Convert the external structure into an internal structure. This stage removes any game-logic, engine transformations, or anything else that may interfere with basic assumptions about the structure. The internal structure should be compatable for any possible use case.
  3. Export the internal structure into a standard format. These often require the use of external libraries to accomodate standard file formats (ex. glTF, PNG).

You may also notice an enum map structure floating about. The goal here is to link integer enumerations with C++ classes to process them. To better explain, here are the steps to use this system:

  1. Create a new abstract class that inherits from EnumMapValue. EnumMapValue has only 1 abstract method that returns an array of processable enumeration values. Example: Extractor.h
  2. Create a new concrete class that implements this interface. Example: model/ModelExtractor
  3. Create a const static EnumMap using the abstract class from step 1 and initilize all the concrete classes. Example: EnumMapExtractor.h

warframe-exporter's People

Contributors

puxtril avatar

Stargazers

Keith Belcher avatar  avatar LieutenantSparkles avatar Gipnoza avatar inxomnyaa avatar  avatar Chronovore avatar  avatar reito avatar James Wilkinson avatar  avatar  avatar Luis avatar  avatar  avatar Whovian9369 avatar Max Halcomb avatar coggy9 avatar  avatar Youn Mélois avatar

Watchers

Emperor avatar Youn Mélois avatar  avatar  avatar Kamikaze avatar  avatar

warframe-exporter's Issues

Terrains not extracting

2.6 alpha 3 terrain is extracted. Later versions do not extract terrains.

Mesh=/Lotus/Levels/CivilianHubs/ObjectiveRooms/ObjEidolonSectorICove/TerrainZ.tmesh
Material=/Lotus/Objects/Ostron/Natural/Terrain/EidolonPlainsRemasterTerrainNoSplat
from RAW file

Level exports > 4GB cause Integer Overflow

The library used for glTF model exporting (fx-gltf) uses uint32_t for buffer sizes. Models greater than 4Gb will cause this to overflow and result in a corrupted model. It's possible to fork the repository and patch this, but I attempted and ran into multiple issues.

The only trigger of this issue is Orb Vallis: /Lotus/Levels/CivilianHubs/VenusLandscape.level

Packages.bin Parsing

Packages.bin has INI metadata for all files, including "virtual" files (i.e. mod card textures and materials, possibly solving #17.) This file used to be uncompressed (and quite large) but for a few years now the format is compressed with ZSTD (similar to #20)

At the moment this format stumps me a bit, here's what I have parsed so far (for packages.bin version 40)

struct STR {
    u32 len;
    char text[len];
};

struct REF {
    STR name;
    u32 unknown;
};

struct ENTITY {
    STR package;
    STR file;
    u8 unknown1;
    if (parent.version >= 36) {
        u16 unknown2;
    } else {
        u32 unknown2;
    }
    STR inherits;
    if (parent.version < 40) {
        u32 unknown3; // 0
    }
    
    // READ from string_buffer until 0 byte starting at where the last entity ended.
    // there is no string offset value.
    // maybe this is what version 34's buffer1 array is for?
};

struct HEADER {
    u8 hash[16];
    u32 header_size; // 20
    u32 version; // 40
    u32 flags; // 1
    if (version >= 40) {
        u32 unknown; // ??
    }

    if (version >= 36) {
        u32 type_count;
        REF types[type_count];
    }

    u32 package_count; // 0 since version 34
    REF packages[package_count];

    if (version >= 34) {
        u32 buffer1_count;
        u8 buffer1[buffer1_count]; // a lot of 0xFF bytes?
        u32 buffer2_count;
        u8 buffer2[buffer2_count]; // suspected zstd compressed data, no header. starts with 0x100000.
        u32 zdict_count;
        u8 zdict[zdict_count];
    } else {
        u32 string_buffer_count;
        u8 string_buffer[string_buffer_count];
    }

    u32 entity_count;
    ENTITY entities[entity_count];
};

HEADER packages @ 0;

New texture compression formats

Lightmap also has textures, which has not been known to contain useful textures until recently. I've discovered 2 new compression formats alongside the usual BC1-7 and 1 uncompressed format.

12 /Lotus/Levels/CorpusGasCityRemaster/GasExit01/LevelCapture_mm.png
30 /Lotus/Levels/ClanDojo/ClanDojoDuviriDeadEnd/Landscape0/T0u0.lchm

Hierarchy of models inside levels

Some models use a relative position instead of absolute. For example inside the level /Lotus/Levels/CivilianHubs/ObjectiveRooms/ObjEidolonSectorICove.level, there exists an entry with attribute Mesh=/Lotus/Objects/Ostron/Structural/OrokinRuns/OroPermieterPylon.fbx. There is likely a hierarchy of models.

Currently this prevents objects from being placed in the scene.

Languages.bin Parser

Here's an Languages.bin Parser in C# for v35. If you have time, you can convert to c++.

Dictionary<string, List<string>> ParseLanguageBin(string fileName) {
    var subtitleDict = new Dictionary<string, List<string>>();

    using var file = File.OpenRead(fileName);
    using var reader = new BinaryReader(file);
    
    var hash = reader.ReadBytes(16);
    var version = reader.ReadInt32();
    var unkA = reader.ReadInt32();
    var unkB = reader.ReadInt32();

    var langCodes = new List<string>();
    var langCount = reader.ReadInt32();
    for (var i = 0; i < langCount; i++) {
        var lang = Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadInt32()));
        langCodes.Add(lang);
    }

    while (reader.BaseStream.Position != reader.BaseStream.Length) {
        var contentSize = reader.ReadInt32();
        var zstdDict = reader.ReadBytes(contentSize);

        var unk0 = reader.ReadInt32();

        using var options = new DecompressionOptions(zstdDict, new Dictionary<ZSTD_dParameter, int>() {
            { (ZSTD_dParameter)1000, 1 }
        });
        using var decompressor = new Decompressor(options);

        for (var k = 0; k < unk0; ++k) {
            var s1Len = reader.ReadInt32();
            var s1 = Encoding.UTF8.GetString(reader.ReadBytes(s1Len));

            // Console.WriteLine($"{reader.BaseStream.Position} {reader.BaseStream.Length} {s1}");

            var s2Len = reader.ReadInt32();
            var s2Bytes = reader.ReadBytes(s2Len);

            var unk1 = reader.ReadInt32(); // array 1 len

            for (var i = 0; i < unk1; ++i) {
                var s3Len = reader.ReadInt32();
                var s3Bytes = reader.ReadBytes(s3Len); // not null terminate
                var s3 = Encoding.UTF8.GetString(s3Bytes);

                var s2Skip = reader.ReadInt32();
                var s2Take = reader.ReadUInt16();
                var s2Flag = reader.ReadUInt16();

                var s2Slice = s2Bytes.AsSpan(s2Skip, s2Take).ToArray();
                var s2 = Encoding.UTF8.GetString(s2Slice);

                if ((s2Flag & 0x200) != 0) {
                    using var br = new BinaryReader(new MemoryStream(s2Slice));
                    var dstLen = br.Read7BitEncodedInt();
                    var srcBuf = br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position));
                    var dst = new byte[dstLen];
                    decompressor.Unwrap(srcBuf, dst, false);
                    s2 = Encoding.UTF8.GetString(dst);
                }

                // Console.WriteLine($"{s1} {s3} {s2Flag:X4} {s2Take} {s2Skip} {s2Bytes.Length} {zstdDict.Length} {s2}");
                subtitleDict.TryAdd(s3, []);
                subtitleDict[s3].Add(s2);
            }
        }
    }

    return subtitleDict;
}

Debugger doesn't handle exception

While using the --debug-models command, it ran into error LotusLib::DecomoressionException and didn't handle it, crashing the program.

Material path length

3D models are exported with empty materials, but the materials are named and assigned to the correct vertices. The material names are exported directly with no formatting. Sometimes the material name length exceeds the Blender limit of 64 characters.

Possible solutions:

  • Clamp material lengths to 64 characters (not good)
  • Remote the beginning material path length. Often what causes these to exceed 64 characters is a full path: ex. /Lotus/Characters/Tenno/Excalibur/SomeMaterial. This can be trimmed to SomeMaterial.
  • Implement the above, but also export the full path to Blender's Custom Properties section. I'm not sure if this is possible with glTF.

Landscape Models

Open-world areas have (in addition to many others) their own model format for landscapes. Inside the cache, they often have the .lndscp file extension, but they always have the Enum value 42 (as of writing this). I have not taken a close look at these, but these would be very good to support full level extraction.

Examples provided by the --print-enums flag:

/Lotus/Levels/InfestedMicroplanet/InfFleshscapeA/2.lndscp
/Lotus/Levels/InfestedMicroplanet/InfFleshscapeA/12.lndscp
/Lotus/Levels/Duviri/WarframeArenas/WFArenasEchoesOfDuviri/FractalPasturesCombat/0.lndscp
/Lotus/Levels/Duviri/MainlandAEast/0.lndscp
/Lotus/Levels/TheNewWar2021/Part1/CetusFire/0.lndscp
/Lotus/Levels/TheNewWar2021/VenusLandscapePostWar/0.lndscp
/Lotus/Levels/TheNewWar2021/CetusPostWar/0.lndscp
/Lotus/Levels/TheNewWar2021/PlainsLandscapePostWar/0.lndscp
/Lotus/Levels/NightWave/TheGlassMaker/CetusCrimeScene/0.lndscp
/Lotus/Levels/CivilianHubs/CetusRemaster/0.lndscp

Floating objects on levels

I believe this is a dynamic system to place models on levels. They are extracting but are placed in the incorrect (up) position. /Lotus/CivilianHubs/ObjectiveRooms/ObjEidolonSectorICove.level

Screenshot_20231203_120827

Vertex colors

From PrVfRu#2715 on discord:

I'll throw a wild guess and propose that what was extracted as vertex tint before(which were deemed broken) were not JUST vertex tints but vertex wear zone +vertex material tints(or maybe something else) + vertex colors assembled into 1 attribute
here`s my proof:

1st ss: wall from ingame. wear is absent on edges, 3 colors. white, red and green
2nd ss: wall from blender, lower one displays red channel from col.001. edges are black. upper one displays blue channel from col.001 with color ramp applied to separate 0-1 range into 4 tints. same deal with floor part behind them.

image

Styanax's Deluxe Spear broken

This model is an exception in multiple areas. Once the Reverse Bind matrices are read, the file position lies at the vertices. But in the 272 reader (and seemingly true for every other 272 model), there are a few more things to be read (see below). So something major in the 272 format is missing here.

  1. Bone pos/rot
  2. 2 unknown attributes for the BoneTree
  3. Skip of 8 bytes

/Lotus/Characters/Tenno/Styanax/ExaltedWeapons/StyanaxDeluxe/StyanaxDeluxeExaltedSpear_skel.fbx

Model format 269 extraction errors

Below are examples.

/Lotus/Characters/Tenno/JetPacks/HarrierSystem/Modular/ModularElytron/ElytronWing_skel.fbx
/Lotus/Characters/Duviri/DuriviOperaSinger/DuviriOperaSingerOutfit_skel.fbx

Animations Missing Postion Scaling

Animation extraction has 3 parts: position, rotation, and scale. Currently I believe scale and rotation are fully working. Position however, is not. Reading position data has 3 parts (I believe): Read the integer value from the file, convert that integer value to the 0.0-1.0 range, then scale that range to the original scale. That could be -10.0 to 10.0 or -20.0 to 5.5, or whatever the original model contained.

I have a good idea where it's stored, but I cannot figure out the extraction method. The models /Lotus/Animations/Infested/InfSpawner/Lean*_anim.fbx are great test subjects because 1 animation has forward, backward, left, and right versions. The Imhex script on the animation branch currently parses animations, but skips important data. Within the action struct read inside skeletons (more specifically, between the name and strideLen fields, should be the position scale. I think. Probably.

More information: https://takinginitiative.wordpress.com/2020/03/07/an-idiots-guide-to-animation-compression/

Missing material data

Material information is useful to model extractors because it provides used textures, default colors, and many other material parameters introduced as materials have grown more complex. Currently the extractor looks for attributes in the Common Header and writes that to a text file. However newer Warframes have been missing these attributes. It's possible materials have a hierarchy for parameters, but texture information should be stored uniquely for each model. I have been unable to find where these missing material parameters are.

As a test case, /Lotus/Characters/Tenno/Dagath/DagathBodyMat contains nothing useful. Her weapon however does contain parameters that can be used on her main model /Lotus/Weapons/Tenno/Melee/Swords/TnDagath/BladeWhip/TnDagathBladeWhipMat.

Material override in levels broke

Level files has override function where material of original mesh can be switched with another one. This behaviour is broken for several extractor updates

Capture (1)
Capture (2)

Some models exporting with geometry errors

May be other examples, but I cannot find them. It seems to be an issue with face indices.

/Lotus/Characters/Tenno/Operator/Heads/OperatorHeadMale_skel.fbx
/Lotus/Characters/Tenno/Operator/Heads/OperatorHeadFemale_skel.fbx
/Lotus/Characters/Tenno/Operator/Heads/AdultOperatorMale_skel.fbx
/Lotus/Characters/Tenno/Operator/Heads/AdultOperatorFemale_skel.fbx

DDS Compressed Texture Format

There are 2 possibilities to export block-compressed textures as DDS. This deals with BC1-BC7 formats.

  1. Do not include a DXT10 header, place a value in the FOURCC field of the DDS Header.
  2. Include a DXT10 header and place a value in the DXGI_FORMAT field, leave the FOURCC value as DXT10.

The ddspp library used by this project currently exports all compressed DDS textures using the second option. Personally, I've found more programs are compatible with the first option, notably GIMP. Of course this is a personal observation, so I have not gathered statistics on what programs/utilities support which format.

There are 2 options to enhance compatibility with other programs:

  1. Fork the ddspp library and modify behavior to match previously mentioned option 1.
  2. Include another library to export textures as PNG rather than DDS. This would add maximum compatibility with other programs, but would definitely require a separate library, and logic to convert DDS to PNG. I choose PNG because it supports transparency, and is the format used by Warframe developers on the backend, as indicated by file extensions within the archive.

Audio preview

Cross-platform audio playback (with a simple UI with pause/play and time scrubbing) is not a simple task in Qt currently. In addition, it should support PCM and Opus codecs. There are a few audio player apps built with Qt, but no framework for building your own widget.

As I write this, I realize Qt seems to support the audio formats/codecs in this repository. But I have not confirmed this.

This is not something I plan on working on, but eventually I may want a working audio playback solution in Qt, in which case I may revisit this.

Pre-Ensmallening Textures

Textures extracted pre-ensmallening have a different compression in the cache files and are processed differently as textures. In the cache, they use LZ decompression. As textures, they need to be unswizzled before written to disk. Textures pre-ensmallening are missing data at the bottom - There's a black line.

I'm not sure if this lies with the unswizzle algorithm, mip0 calculation, or LZ decompression.

.\Warframe-Exporter-Advanced.exe --internal-path /Lotus/Characters/Tenno/Excalibur --cache-dir Z:\steam\232461576962714068\Cache.Windows --extract-textures --pre-ensmall-1

Excalibur_d_gen1

Static models incorrect rotation

Static models do not import with the correct rotation relative to their related rigged models. As an example, this is Ember with some armor attachments rotated 180 degrees on the Z axis.

Capture.PNG

Capture-1.PNG

[Documentation] README is missing information on building

So I accidentally hit CTRL+ENTER before actually typing the issue, sorry!

The actual issue:
It would be nice to have some more info in the "Building" Section that building on Linux can be done by:

  • Downloading Unreal Engine from the official Linux page (though logging in is required)
  • Extracting the zip's Engine/Source/Runtime/OodleDataCompression/Sdks/2.9.5/lib/ to ./bin/.

Example file list of ./bin/ for my successful build:

$ ls -1N bin/
Android
IOS
Linux
LinuxArm64
Mac
TVOS
Win32
Win64

Model Extraction error

Reported by a user on Discord. Could not get this duplicated on my system, will need to investigate more.

image

Multi-threaded Oodle Decompression

The Oodle compression library is added for only 1 function: OodleLZ_Decompress. It seems this function is single-threaded, because it throws a temper tantrum when multi-threaded (see below for errors). According to the function signature, there are parameters to allocate memory for decompression operations. I assume this will allow for separated memory, thus thread-safe execution. But I have yet to implement this in LotusLib, and it would prove difficult considering the layers of abstractions I added between the user interface and actual file decompression (my actions have finally yielded consequences).

This is noticeable when attempting to preview models in the UI while trying to index vertex colors in the background (currently disabled).

Oodle complaining:

OODLE ERROR : corruption : inconsistency detected during phase 2
OODLE ERROR : LZ corruption : DecodeOneQuantum fail!
OODLE ERROR : LZ corruption : OodleLZ_Decompress failed (0 != 335)
OODLE ERROR : corruption : inconsistency detected during phase 2
OODLE ERROR : LZ corruption : DecodeOneQuantum fail!
OODLE ERROR : LZ corruption : OodleLZ_Decompress failed (0 != 1446)
OODLE ERROR : corruption : inconsistency detected during phase 2
OODLE ERROR : LZ corruption : DecodeOneQuantum fail!
OODLE ERROR : LZ corruption : OodleLZ_Decompress failed (0 != 262144)
OODLE ERROR : corruption : bad packets
OODLE ERROR : LZ corruption : DecodeOneQuantum fail!
OODLE ERROR : LZ corruption : OodleLZ_Decompress failed (0 != 219)
OODLE ERROR : corruption : inconsistency detected during phase 2
OODLE ERROR : LZ corruption : DecodeOneQuantum fail!
OODLE ERROR : LZ corruption : OodleLZ_Decompress failed (0 != 1926)
OODLE ERROR : corruption : inconsistency detected during phase 2
OODLE ERROR : LZ corruption : DecodeOneQuantum fail!
OODLE ERROR : LZ corruption : OodleLZ_Decompress failed (0 != 1671)

New Texture Extraction Method

Currently, the texture resolution needs to be calculated dynamically. Warframe provides a resolution, but this should only be used for the texture resolution ratio. The formula to calculate the actual resolution is a bit clunky.

Thanks to a discovery by @sehnryr (detailed in sehnryr/wfcache-api#1), this will be a lot simpler. Not a huge priority as the current implementation is fast enough and works without issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.