• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

June 2013 News Batch

Status
Not open for further replies.
Level 30
Joined
Jul 31, 2010
Messages
5,259

Hive Workshop © June 2013:
194715-albums6441-picture69839.png
CONTRIBUTIONS BY:

194715-albums6441-picture71313.png
Deolrin
Models Spotlight
f25b6d08e0aa146ff793347359ebf211_69933.png
Magtheridon96
Spells Spotlight & Hive Quiz
[The icon will directly take you to its destination when clicked.]

194715-albums6441-picture71526.jpg
Top 3 Resources
194715-albums6441-picture71544.jpg
Project's Spotlight
194715-albums6441-picture71543.jpg
Hive's Arena
194715-albums6441-picture71547.jpg
Hive Quiz
194715-albums6441-picture71556.jpg
Community Spotlight
194715-albums6441-picture71555.jpg
News

194715-albums6441-picture71525.jpg

[Click the tabs below to switch between different Resource Spotlights]

Maps

Models

Icons

Spells

194715-albums6441-picture71759.jpg
melee_8.gif
Hegemony
Type: Melee
Category: Medieval / Warcraft
Author: normalice

addrev.gif
addrev.gif
addrev.gif
addrev.gif
addrev.gif
(Highly Recommended)
01c968117abc07c8795b955503a61e4e_69844.gif

194715-albums6441-picture71760.jpg
custom_1.gif
Poison Forest Template
Type: Template / Terrain
Category: Medieval / Warcraft
Author: finlandman_co

a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
(Highly Recommended)
194715-albums6441-picture71761.jpg
custom_4.gif
Emerald Glade
Type: Melee
Category: Medieval / Warcraft
Author: z.ky

a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
11e1bf8437d599ca26f1f4372e63b8ad_69843.gif
(Recommended)
01c968117abc07c8795b955503a61e4e_69844.gif

194715-albums6441-picture71762.jpg
Azure Dragon Crystal Lord
Type: Hero
Category: Creep
Author(s): Frankster

a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
(Director's Cut)
194715-albums6441-picture71763.jpg
DoC Azerothian Footman
Type: Unit
Category: Human
Author: John_Drake

a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
11e1bf8437d599ca26f1f4372e63b8ad_69843.gif
(Recommended)
194715-albums6441-picture71764.jpg
WoW Kil'jaeden
Type: Hero
Category: Demon
Author: takakenji

a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
a2a855b6c4964e8283a0b4a0b9802ed6_69842.gif
11e1bf8437d599ca26f1f4372e63b8ad_69843.gif
(Recommended)



BTNMind by PeeKay

BTNTrollSight by PeeKay

BTNZword by NFWar

194715-albums6441-picture71765.jpg
DDS - Damage Detection System
Type: System, Template
Category: vJASS
Author: Nestharus

addrev.gif
addrev.gif
addrev.gif
addrev.gif
addrev.gif
(Director's Cut)
01c968117abc07c8795b955503a61e4e_69844.gif

194715-albums6441-picture71766.jpg
Advanced Maths & Ingame Calculator
Type: System
Category: vJASS
Author: looking_for_help

addrev.gif
addrev.gif
addrev.gif
th_blankrev.gif
th_blankrev.gif
(Useful)
194715-albums6441-picture71767.jpg
Chaos Envoy V1.02
Type: Target, Ground
Category: JASS
Author: Tank-Commander

th_blankrev.gif
th_blankrev.gif
th_blankrev.gif
th_blankrev.gif
th_blankrev.gif
(Not Rated)
01c968117abc07c8795b955503a61e4e_69844.gif




194715-albums6441-picture71545.jpg


Tides of War - Tides of War is a campaign based on the book Tides of War.
The main characters are Jaina Proudmoore and Sylvanas Windrunner.>>
Read more about the storyline in its Map Development thread.

This map development has been chosen as the Top Project Spotlight for May'June



194715-albums6441-picture71542.png



  • Icon Contest #11 - The Results
    • The Results are in place, let us congratulate the winners of the contest!


194715-albums6441-picture71546.jpg


Hive Quiz JASS Questions:

  • [1 Rep] What is storm.dll? Name 3 API functions.
  • [3 Rep] Give a pair of strings that return the same hash when passed to it.
  • [5 Rep] Write an algorithm to read and parse a TFT .doo file. (Bonus: Write code to parse it in any programming language other than (v)JASS, including the code needed to read it assuming it exists as an individual file in some relative path. Any non-esoteric programming language will be acceptable.)


194715-albums6441-picture71528.jpg


The Vietnamese Modding Council - Is a social group made for Vietnamese users only, The group's main purpose is to provide modding-related help and assist noble Vietnamese modders in all aspects of their daring Warcraft III projects.


Users MrStormyZ and Azothan has presented a latest release of warcraft III related videos!







194715-albums6441-picture71554.jpg



 
Last edited:
Give a pair of strings that return the same hash when passed to it.

a
A

[1 Rep] What is storm.dll? Name 3 API functions.

The dll for manipulating mpq archives.

Code:
bool WINAPI SFileReadFile(
  HANDLE hFile,                     // File handle
  VOID * lpBuffer,                  // Pointer to buffer where to read the data
  DWORD dwToRead,                   // Number of bytes to read
  DWORD * pdwRead,                  // Pointer to variable that receivs number of bytes read
  LPOVERLAPPED lpOverlapped         // Pointer to OVERLAPPED structure
);

bool WINAPI SFileOpenFileEx(
  HANDLE hMpq,                      // Archive handle
  const char * szFileName,          // Name of the file to open
  DWORD dwSearchScope,              // Specifies the scope for the file.
  HANDLE * phFile                   // Pointer to file handle
);

DWORD WINAPI SFileGetFileSize(
  HANDLE hFile,                     // File handle
  DWORD * pdwFileSizeHigh           // High 32 bits of the file size.
);

As for the last, too lazy
 
a
A



The dll for manipulating mpq archives.

Code:
bool WINAPI SFileReadFile(
  HANDLE hFile,                     // File handle
  VOID * lpBuffer,                  // Pointer to buffer where to read the data
  DWORD dwToRead,                   // Number of bytes to read
  DWORD * pdwRead,                  // Pointer to variable that receivs number of bytes read
  LPOVERLAPPED lpOverlapped         // Pointer to OVERLAPPED structure
);

bool WINAPI SFileOpenFileEx(
  HANDLE hMpq,                      // Archive handle
  const char * szFileName,          // Name of the file to open
  DWORD dwSearchScope,              // Specifies the scope for the file.
  HANDLE * phFile                   // Pointer to file handle
);

DWORD WINAPI SFileGetFileSize(
  HANDLE hFile,                     // File handle
  DWORD * pdwFileSizeHigh           // High 32 bits of the file size.
);

As for the last, too lazy

Correct and Correct.
(+4)
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
[5 Rep] Write an algorithm to read and parse a TFT .doo file. (Bonus: Write code to parse it in any programming language other than (v)JASS, including the code needed to read it assuming it exists as an individual file in some relative path. Any non-esoteric programming language will be acceptable.)
Sounds like a job for Java.

[1 Rep] What is storm.dll? Name 3 API functions.
Is this legal?
 
Yes but has Blizzard licenced people to use the .dll? All those headers are unofficial as far as I am aware, created via reverse-engineering. There is a difference between being able to use and can use.

Yeah, they are unofficial. And no, Blizzard has not licensed it.

However, Blizzard does not care. MPQ editing keeps players going/occupied, since it allows people to create more interesting mods (e.g. WoW Model Viewer for machinima).

Chances are that it is against their EULA. But we already do so many things against their EULA, so oh well. :p
 
The .doo file? easy, i believe i already can parse one. Give me a few.

war3map.doo right? the tree file.

Here it is: Compile it with -std=c++0x OR -std=c++11
C++:
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

struct ObjectId{
    union{
        int Integer;
        char Bytes[4u];
    };
};

const char tf_Invis_NonSolid(0);
const char tf_Vis_NonSolid(1);
const char tf_Vis_Solid(2);

enum ItemType{it_Any='Y',it_Permanent='i',it_Charged,it_PowerUp,it_Artifact,it_Purchasable,it_Campaign,it_Miscellaneous,it_None='\0'};

struct DroppedItem{
    ObjectId ItemId;
    int ChanceToDrop;
    bool IsRandom()const{
        return ItemId.Bytes[0u]=='Y'&&ItemId.Bytes[2u]=='I';
    }
    ItemType GetRandomItemType()const{
        switch(ItemId.Bytes[1u]){
            case 'Y':return it_Any;
            case 'i':return it_Permanent;
            case 'j':return it_Charged;
            case 'k':return it_PowerUp;
            case 'l':return it_Artifact;
            case 'm':return it_Purchasable;
            case 'n':return it_Campaign;
            case 'o':return it_Miscellaneous;
            default:return it_None;
        }
    }
    int GetRandomItemLevel()const{
        return int(ItemId.Bytes[3u])-48; // return of -1 means any level.
    }
};

typedef vector<DroppedItem> ItemSet;

struct Tree{
    ObjectId Id;
    int Variation;
    float X;
    float Y;
    float Z;
    float Angle;
    float ScaleX;
    float ScaleY;
    float ScaleZ;
    char Flags;
    char Life;
    int ItemTablePointer;
    vector<ItemSet> DroppedSets;
    int WorldEditorId;
};

struct SpecialDoodad{
    ObjectId Id;
    int Z;
    int X;
    int Y;
};

struct DoodadFile{
    ObjectId FileId;
    int Version;
    int Subversion;
    vector<Tree> Trees;
    int SpecialDoodadFormat;
    vector<SpecialDoodad> SpecialDoodads;
};

DoodadFile ParseTrees(ifstream& FileStream);
DoodadFile ParseTreesWrapper(const string& FileName){
    ifstream File(FileName.c_str(),ifstream::in|istream::binary);
    if(File)return ParseTrees(File);
    return DoodadFile();
}

int main(int NumFiles,char** FileNames){
    if(NumFiles>1){
        for(int FileIndex=1;FileIndex<NumFiles;FileIndex++){
            cout<<"Trees: "<<ParseTreesWrapper(string(FileNames[FileIndex])).Trees.size()<<endl;
        }
    }
    char C;
    cin>>C;
    return 0;
}

DoodadFile ParseTrees(ifstream& FileStream){
    DoodadFile Ret;
    FileStream.read((char*)&Ret.FileId.Integer,4u);
    FileStream.read((char*)&Ret.Version,4u);
    FileStream.read((char*)&Ret.Subversion,4u);
    unsigned int NumberOfTrees=0u;
    FileStream.read((char*)&NumberOfTrees,4u);
    Ret.Trees.resize(NumberOfTrees);
    for(Tree& Iter:Ret.Trees){
        FileStream.read((char*)&Iter.Id.Integer,4u);
        FileStream.read((char*)&Iter.Variation,4u);
        // Position
        FileStream.read((char*)&Iter.X,4u);
        FileStream.read((char*)&Iter.Y,4u);
        FileStream.read((char*)&Iter.Z,4u);
        // Rotation
        FileStream.read((char*)&Iter.Angle,4u);
        // Scale
        FileStream.read((char*)&Iter.ScaleX,4u);
        FileStream.read((char*)&Iter.ScaleY,4u);
        FileStream.read((char*)&Iter.ScaleZ,4u);
        // Rest
        FileStream.read(&Iter.Flags,1u);
        FileStream.read(&Iter.Life,1u);
        // Begin Item Set Parsing.
        FileStream.read((char*)&Iter.ItemTablePointer,4u);
        if(Iter.ItemTablePointer==-1){
            unsigned int ItemSets=0u;
            FileStream.read((char*)&ItemSets,4u);
            Iter.DroppedSets.resize(ItemSets);
            for(ItemSet& Set:Iter.DroppedSets){
                unsigned int ItemsInSet=0u;
                FileStream.read((char*)&ItemsInSet,4u);
                Set.resize(ItemsInSet);
                for(DroppedItem& Item:Set){
                    FileStream.read((char*)&Item.ItemId.Integer,4u);
                    FileStream.read((char*)&Item.ChanceToDrop,4u);
                }
            }
        }
        FileStream.read((char*)&Iter.WorldEditorId,4u);
    }
    FileStream.read((char*)&Ret.SpecialDoodadFormat,4u);
    unsigned int SpecialDoods=0u;
    FileStream.read((char*)&SpecialDoods,4u);
    Ret.SpecialDoodads.resize(SpecialDoods);
    for(SpecialDoodad& Doodad:Ret.SpecialDoodads){
        FileStream.read((char*)&Doodad.Id.Integer,4u);
        FileStream.read((char*)&Doodad.Z,4u);
        FileStream.read((char*)&Doodad.X,4u);
        FileStream.read((char*)&Doodad.Y,4u);
    }
    return Ret;
}

What bonus points do i earn? lol

String Hash thing, any two strings differing in only case. (herro and HeRrO)
 
Last edited:
Sounds somewhat true, I think right before the owner said I stole it, the process of apologizing looks very vague to some. I can't decide about that.

Well, you are a moderator and what you just did does not justifies your position in any way.
Aaaaaand considering this conversation and the goofy meme, I think that I can speak for most people and simply say you fucked it up in a big way.

Not only that you claimed what ain't yours, you made the assumption that most people are too dump and won't see this and you make yourself look like a very bad guy, which you are not I hope.
 
Level 30
Joined
Jul 31, 2010
Messages
5,259
Let's add more color to the picture then, I also want to say that I did not ask permissions to the other images I used for the news, so most of the them are in the terrain board so should this be an amplifier to the cause? sadly no.

Maybe its just the owner/s's privacy that I barged in and not the community, it doesn't looked so fucked up when you actually have the guts to say something that will tone down the issue, more over getting caught and show much annotation(this is the internet by the way, so I'm probably lying) you have can be an earnest decision.

I'm never the good guy, I'm never been called the goody-good shoes around here if you plan to browse my history.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Zeatherann your solution uses too many read calls. Read calls are expensive and in some implementations they even go out as an OS call each. You also fail to exploit the fact that on some platforms the structure elements may be unchanged.

You should rather read the entire file into a buffer in a single call and then interpret that buffer into native structures. You should also use an abstract read method since there would otherwise be no way to chain it from a stream coming from an MPQ (where .doo files mostly are found).

You also fail to parse the unit and item .doo file. Yes there are 2 .doo files which have some similarities but also differences.
 
Alrighty, ifstream read calls are not as bad as you pretend they are (they use an internal buffer). If it makes you happy i'll gladly read the file into a stringstream first though. I'll quickly add a way to read war3mapunits.doo as well. I'm sure the headers differ on them.

Also: there is no way to reliably take 50 bytes and turn them into a struct, as the order of the member variables could be swapped, or could be padded to make the aligned.

Platforms that I want this to support: Windows, MacOS. (Since war3 is only on those two)

Edit: I did ask which .doo file btw, but you failed to answer before i posted my code.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Also: there is no way to reliably take 50 bytes and turn them into a struct, as the order of the member variables could be swapped, or could be padded to make the aligned.
There is, and it is required as your implementation does not factor in endian. Thus if it compiles on Mac it will break but Windows it will work.

The idea is you take a pseudo structure (an array of bytes) with a known, platform independent, format and convert it into a native structure with platform dependant structure. This is the process known as de-serialization.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
practically everyone's using IEEE-754
Except Sony who did not use it in their PlayStation 2. In fact, that is a major problem with emulator compatibility.

The .doo is a real mess of dynamic data structures. Especially handling RoC/TFT compatibility since the lack of consistency makes neat code difficult to make. Frankly anything that fails to handle both versions is not at all useful.

So far I have doodads working for both versions. Units are a lot more complicated as they contain a lot more data and more annoying changes.
 
Compile with -std=c++0x or -std=c++11

C++:
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;

// Endian Code

template<typename Type>Type SwapEndian(const Type& BytesToSwap){
    return ((((BytesToSwap) & 0xff000000) >> 24)|(((BytesToSwap) & 0x00ff0000) >>  8)|(((BytesToSwap) & 0x0000ff00) <<  8)|(((BytesToSwap) & 0x000000ff) << 24));
}

int ReadInteger(char* Bytes){
#if defined(_WIN32) || defined(__WIN32__)
    return *((int*)Bytes);
#else
    // Swap to big-endian
    return SwapEndian<int>(*((int*)Bytes));
#endif // WIN32
}

float ReadFloat(char* Bytes){
#if defined(_WIN32) || defined(__WIN32__)
    return *((float*)Bytes);
#else
    // Swap to big-endian
    return SwapEndian<float>(*((float*)Bytes));
#endif // WIN32
}

#define GrabInt(Where) Stream.read(Buffer,4u);Where=ReadInteger(Buffer)
#define GrabFloat(Where) Stream.read(Buffer,4u);Where=ReadFloat(Buffer)

struct ObjectId{
    union{
        int Integer;
        char Bytes[4u];
    };
};

enum ItemType{it_Any='Y',it_Permanent='i',it_Charged,it_PowerUp,it_Artifact,it_Purchasable,it_Campaign,it_Miscellaneous,it_None='\0'};

struct DroppedItem{
    ObjectId ItemId;
    int ChanceToDrop;
    bool IsRandom()const{
        return ItemId.Bytes[0u]=='Y'&&ItemId.Bytes[2u]=='I';
    }
    ItemType GetRandomItemType()const{
        switch(ItemId.Bytes[1u]){
            case 'Y':return it_Any;
            case 'i':return it_Permanent;
            case 'j':return it_Charged;
            case 'k':return it_PowerUp;
            case 'l':return it_Artifact;
            case 'm':return it_Purchasable;
            case 'n':return it_Campaign;
            case 'o':return it_Miscellaneous;
            default:return it_None;
        }
    }
    int GetRandomItemLevel()const{
        return int(ItemId.Bytes[3u])-48; // return of -1 means any level.
    }
};

typedef vector<DroppedItem> ItemSet;

struct Tree{
    ObjectId Id;
    int Variation;
    float X;
    float Y;
    float Z;
    float Angle;
    float ScaleX;
    float ScaleY;
    float ScaleZ;
    char Flags;
    char Life;
    int ItemTablePointer;
    vector<ItemSet> DroppedSets;
    int WorldEditorId;
};

struct SpecialDoodad{
    ObjectId Id;
    int Z;
    int X;
    int Y;
};

struct DoodadFile{
    ObjectId FileId;
    int Version;
    int Subversion;
    vector<Tree> Trees;
    int SpecialDoodadFormat;
    vector<SpecialDoodad> SpecialDoodads;
};

bool ReadDoodadFile(DoodadFile& Return,char* FileData,unsigned int FileSize){
    stringstream Stream(stringstream::out|stringstream::in|stringstream::binary);
    char Buffer[4u]="\0\0\0";
    if(!Stream.write(FileData,FileSize))return false;
    try{
        // Read File Header Data.
        Stream.read(Return.FileId.Bytes,4u);
        GrabInt(Return.Version);
        GrabInt(Return.Subversion);
        // Read Trees.
        Stream.read(Buffer,4u);
        Return.Trees.resize(ReadInteger(Buffer));
        for(Tree& TreeIter:Return.Trees){
            Stream.read(TreeIter.Id.Bytes,4u);
            GrabInt(TreeIter.Variation);
            // Position
            GrabFloat(TreeIter.X);
            GrabFloat(TreeIter.Y);
            GrabFloat(TreeIter.Z);
            // Rotation
            GrabFloat(TreeIter.Angle);
            // Scale
            GrabFloat(TreeIter.ScaleX);
            GrabFloat(TreeIter.ScaleY);
            GrabFloat(TreeIter.ScaleZ);
            // Rest
            Stream.read(&TreeIter.Flags,1u); // Byte
            Stream.read(&TreeIter.Life,1u); // Byte
            // Begin Item Set Parsing.
            GrabInt(TreeIter.ItemTablePointer);
            if(TreeIter.ItemTablePointer==-1){
                Stream.read(Buffer,4u);
                TreeIter.DroppedSets.resize(ReadInteger(Buffer));
                for(ItemSet& Set:TreeIter.DroppedSets){
                    Stream.read(Buffer,4u);
                    Set.resize(ReadInteger(Buffer));
                    for(DroppedItem& Item:Set){
                        Stream.read(Item.ItemId.Bytes,4u);
                        GrabInt(Item.ChanceToDrop);
                    }
                }
            }
            GrabInt(TreeIter.WorldEditorId);
        }
        // Read Special Doodads.
        Stream.read(Buffer,4u);
        Return.SpecialDoodads.resize(ReadInteger(Buffer));
        for(SpecialDoodad& Doodad:Return.SpecialDoodads){
            Stream.read(Doodad.Id.Bytes,4u);
            GrabFloat(Doodad.Z);
            GrabFloat(Doodad.X);
            GrabFloat(Doodad.Y);
        }
    }catch(...){
        return false;
    }
    return true;
}

Don't forget to give your own main function.
 
It's actually 5 rep for the algorithm, the code was part of the bonus, so this is like +10 :p

Only problem with the code is that it assumes everything that isn't Windows is Big Endian. Apple doesn't even use PowerPC anymore, I'm on an Intel Mac and the Endianness is Little :/

I'm not going to be pedantic however, and I'll just give the reward because you have something that reads the file and parses it into correct sets of data, so here you go, +10.

Anyways, all questions have been answered for Hive Quiz, so don't bother answering them.

THEN AGAIN, if I can see more implementations of the last one in different languages, I'll be happy to give more +10s ;D
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Magtheridon96, My Java solution is delayed due to the damn trickery they do with Units and Items. I only have the Trees and Terrain being processed correctly at the moment (I tested it one a file and the values loaded made sense). Best part is that it should be completely platform independent once it is done.

The difficult part is...
Code:
int: random unit/item flag "r" (for uDNR units and iDNR items)
0 = Any neutral passive building/item, in this case we have
  byte[3]: level of the random unit/item,-1 = any (this is actually interpreted as a 24-bit number)
  byte: item class of the random item, 0 = any, 1 = permanent ... (this is 0 for units)
  r is also 0 for non random units/items so we have these 4 bytes anyway (even if the id wasn't uDNR or iDNR)
1 = random unit from random group (defined in the w3i), in this case we have
  int: unit group number (which group from the global table)
  int: position number (which column of this group)
  the column should of course have the item flag set (in the w3i) if this is a random item
2 = random unit from custom table, in this case we have
  int: number "n" of different available units
  then we have n times a random unit structure
How is one meant to represent this... It makes sense from a resolving point of view as you would convert it into some random unit structure ultimately, but without doing that...

In C you would probably bundle a extra piece of memory for it with a pointer and use the int value r to dictate how algorithms interpret that memory (I am guessing this is how WE/WC3 does it), but in Java you have to define the types of all values unless you want it to be kept in a serialized format (inefficient as the JVM may not optimize efficiently).

I could declare members for all possible values but that would be inefficient as only 1 set of them is ever used at any time.
 
Level 14
Joined
Nov 18, 2007
Messages
816
In C, you can cast variables to types that have nothing whatsoever to do with the original type. You cant do that in Java (except maybe for some hacks that i would never want to touch with a ten foot pole).

EDIT:

have fun with these

de/deaod/wc3doo/WidgetFile.java
de/deaod/wc3doo/InvalidFileFormat.java
de/deaod/wc3doo/DataReader.java

Doesnt work, mostly because the publicly available documentation sucks ass and im not about to spend the rest of the evening reversing wtf is going on in these files. Maybe you want to though, so here we are.
I'd appreciate getting changes back.

License: standard BSD 3-clause license
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Deaod, why you not using a ByteBuffer... You know, the class specially designed to handle endian types, you even use its endian definition.

You abuse stream reads heavily and use the deprecated stream system. You should be buffering more content to avoid unnecessary stream reading.
 
Level 14
Joined
Nov 18, 2007
Messages
816
To my knowledge, java.io is a decent synchronous io package. It hasnt been deprecated, and works well enough to be used for simple demonstration implementations.

I appreciate the feedback, and ill probably look into what little pointers you gave. Until then, you are free to rewrite that code as you see fit. Im sure you can make a lot of improvements, which i would be most excited to review for learning purposes.
 
Level 14
Joined
Nov 18, 2007
Messages
816
Just a quick update. The version i posted should now work for ROC and TFT .doo files.

I cant make any promises because to really test that youd need a lot of test cases which im too lazy to generate right now. There could always be a so called "flag" that currently isnt handled (hell, the majority are undocumented).

Whoever documented the .doo file format for units/items didnt do his homework.
int: random unit/item flag "r" (for uDNR units and iDNR items)
This value is sometimes -1 as well. Specifically, its -1 for start locations. You handle this case by ignoring it. The next value that should be parsed from the file is the custom color.

Im also now buffering the file input stream for those who care.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
To my knowledge, java.io is a decent synchronous io package. It hasnt been deprecated, and works well enough to be used for simple demonstration implementations.
Its deprecated because it only supports 2GB files, does not support random access well and has no support for memory mapping.

Since it is so heavily used, they could not remove it or change it so instead they added nio, short for New Input Output.

This system uses ByteBuffer to allow endian independence and all file positions are longs for support of files greater than 2GB. A lot of optimization have gone into buffers in Java 7 as well. Direct buffers have performance almost identical to C code in some ways.

New Java programs should avoid the old io in favour of nio. Adapters exist to convert between the two stream formats however these are only for compatibility. In reality Java does file IO only using nio Classes. The ones you see in io package are wrappers around nio Classes.
 
Status
Not open for further replies.
Top