Entidad 3D :: Creación de juegos en 3D sin programar

Foro de Entidad 3D
 
PortalÍndiceBuscarMiembrosGrupos de UsuariosFAQChatAnalisisRegistrarseConectarse
. . . . . . . . . . . . . . . . . . . . . . . .
Visita el sitio oficial de Entidad 3D para descargar la última versión!
Si encuentras un bug en la útlima versión de Entidad 3D, comunícaselo directamente al autor de Entidad 3D, Jordi Perez via correo electronico. Si no estás seguro si es un bug o no, consúltalo con la gente del foro!
Si eres un usuario nuevo preséntate en el subforo de saludos y despedidas para asegurar tu cuenta! (Los usuarios que tengan 0 mensajes pasados los primeros 10 días de creada su cuenta serán eliminados como política de limpieza del foro)

Comparte | 
 

 Ingenieria inversa League of Legends

Ver el tema anterior Ver el tema siguiente Ir abajo 
AutorMensaje
estantaya
Avanzado
Avanzado
avatar

Último Juego : Sur Survival
Sexo : Masculino
Mensajes : 273
Edad : 30
Localización : Mi casa

MensajeTema: Ingenieria inversa League of Legends   Sáb Oct 04, 2014 1:25 am

Hola, estoy aprendiendo un poco sobre ingenieria inversa, porque quiero actualizar un programa que convierte archivos de skin del juego League of Legends en un formato que se puede editar y luego volver el archivo skin nuevamente.

por ahora logre que vuelva a convertir archivos .skn aunque solo funciona en la version 2
originalmente este programa convertia de la version 1
algunos modelos skin son version 4
y la estructura binaria dentro de ellos es diferente
eso estoy actualizando, por ahora estube abriendo con mi visor hexadecimal los archivos .skn y modifique la estructura como me parecio...

una de las cosas que quiero hacer es que el programa exporte a otros formatos el actual es .obj pero ese formato no acepta el esqueleto del modelo y eso es escencial si se quiere crear un custom skin con nuevos grupos de caras/vertices etc y su respectiva mapa de textura...

como estoy usando unity 3d me parecio que .fbx seria una solución pero los archivos fbx son muy complejos y no encuentro un manual simple que pueda entender en donde simplemente me diga como es su estructura de datos... si descargo el sdk correspondiente me podria servir pero me parecio que era algo complejo :S


Código:

/*
League of Legends Custom Skin Tool-Kit
by Jahrain
This is a simple tool that can be used to compile and decompile .skn and .skl files
in order to create custom skin models for League of Legends

Modificado por estantaya en octubre de 2014
[Tienes que estar registrado y conectado para ver este vínculo]
*/
#include<iostream>
#include<fstream>
#include<vector>
#include<string>
using namespace std;

struct FbxHeader {
      char String1[20];//Kaydara FBX Binary 
      int Short1;
      int Int1;
      int Int2;
      char String2[20];//FBXHeaderExtension\
      int Short2;
      int Short3;
      char String3[20];//FBXHeaderVersionI
      char String4;//x
      int Int3;
      int Int4;
      char String5[14];//FBXVersionIp
      int Int5;
      int Int6;
      char String6[16];//EncryptionTypeI
      int Int7;
      char String7[20];//CreationTimeStamp
      int Int8;
      char String8[11];//VersionIè
      int Int9;
      int Int10;
      char String9[8];//YearIÞ
      int Int11;
      int Int12;
      int Int13;
      char String10[8];//MonthI
      int Int14;
      int Int15;
      int Int16;
      char String11[6];//DayI
      int Int17;
      int Int18;
      int Int19;
      char String12[7];//HourI
      int Int20;
      int Int21;
      int Int22;
      char String13[9];//MinuteI
      int Int23;
      int Int24;
      int Int25;
      char String14[9];//SecondI
      int Int26;
      int Int27;
      int Int28;
      char String15[15];// MillisecondI?
      int Int29;
      int Int30;
      int Int31;
      char String16[10];//CreatorS"
      char String17[36];//FBX SDK/FBX Plugins build 20050830ù
      char String18[13];//OtherFlagsì
      int Int32;
      int Int33;
      char String19[9];//FlagPLEI
     
     
};

struct SklHeader {
   //Structure for header on skl files
   unsigned char fileType[8];
   
   //nueva estructura
   unsigned int version;
   unsigned int designerID;
   
   unsigned int numElements;
   
   //int numObjects;
   //int skeletonHash;
};
 
struct SklHeaderX {
    //Structure for header on skl files
    char fileType[8];
    int numObjects;
    int skeletonHash;
    unsigned int numElements;
};

struct Bone {
   //Structure for a bone in skl files
   char name[32];      //nombres normales
   int parent;
   float scale;
   float matrix[3][4];
};

struct BoneX {
   //Structure for a bone in skl files
   int nameId;      //nombres guardados en indices
   int parent;
   float scale;
   float matrix[3][4];
};

struct SkinModelHeader {
   //Structure for the Header in skn files
   int magic;
   short version;      //estructura nueva
   short numObjects;
   int numMaterials;  //no es short ahora es int
};
struct SkinModelMaterial {
   //Structure for a material block in skn files
   
   char name[64];
   //int matIndex;
   
   int startVertex;
   int numVertices;
   int startIndex;
   int numIndices;
};
struct SkinModelVertex {
   //Vertex block in skn files
   float position[3];
   char  boneIndex[4];
   float weights[4];
   float normal[3];
   float texcoords[2];
};
struct SkinModelData {
   //data block in skn files
   int numIndices;
   int numVertices;
   vector<short> indices;
   vector<SkinModelVertex> verteces;
};

struct SkinModel {
   //Skin model data structure
   SkinModelHeader header;
   vector<SkinModelMaterial> materials;
   SkinModelData modelData;


   void exportObj(string fileName) {
      //exports this skin model as a .obj file
      ofstream fout(fileName.c_str());
      for (int i = 0; i < modelData.verteces.size(); i++) {
         fout << "v " << modelData.verteces[i].position[0] << " " << modelData.verteces[i].position[1] << " " << modelData.verteces[i].position[2] << endl;
         fout << "vn " << modelData.verteces[i].normal[0] << " " << modelData.verteces[i].normal[1] << " " << modelData.verteces[i].normal[2] << endl;
         fout << "vt " << modelData.verteces[i].texcoords[0] << " " << 1-modelData.verteces[i].texcoords[1] << endl;
      }
      if (materials.size()) {
         fout << "g mat_" << materials[0].name << endl;
      }
      for (int i = 0;  i < modelData.numIndices/3; i++) {
         int a = modelData.indices[i*3] + 1;
         int b = modelData.indices[i*3 + 1] + 1;
         int c = modelData.indices[i*3 + 2] + 1;
         fout << "f " << a << '/' << a << '/' << a << " " << b << '/' << b << '/' << b << " " << c << '/' << c << '/' << c << endl;
      }
   }


   void exportSkn(string fileName) {
      //export this SkinModel as .skn which can be used by league of legends
      ofstream fout;
      fout.open(fileName.c_str(), ios::binary);
      fout.write((char*)(void*)&header,sizeof(SkinModelHeader));
      for (int i = 0; i < header.numMaterials; i++) {
         fout.write((char*)(void*)&materials[i], sizeof(SkinModelMaterial));
      }
      fout.write((char*)(void*)&modelData.numIndices,4);
      fout.write((char*)(void*)&modelData.numVertices,4);
      for (int i = 0; i < modelData.numIndices; i++) {
         fout.write((char*)(void*)&modelData.indices[i], 2);
      }
      for (int i = 0; i < modelData.numVertices; i++) {
         fout.write((char*)(void*)&modelData.verteces[i],sizeof(SkinModelVertex));
      }
   }


   void exportFbx(string fileName) {
      //lee fbx, muestra resultado
      ifstream fin;
      fin.open(fileName.c_str(), ios::binary);
      FbxHeader fbxHeader;
      fin.read((char*)(void*)&fbxHeader,sizeof(FbxHeader));
      cout << "int: " << fbxHeader.Int1 << "." << endl;
      cout << "int: " << fbxHeader.Int2 << "." << endl;
      cout << "int: " << fbxHeader.Int3 << "." << endl;
      cout << "int: " << fbxHeader.Int4 << "." << endl;
      cout << "int: " << fbxHeader.Int5 << "." << endl;
      cout << "int: " << fbxHeader.Int6 << "." << endl;
      
      cout << "short: " << fbxHeader.Short1 << "." << endl;
      cout << "short: " << fbxHeader.Short2 << "." << endl;
      cout << "short: " << fbxHeader.Short3 << "." << endl;
      
      cout << "string: " << fbxHeader.String1 << "." << endl;
      cout << "string: " << fbxHeader.String2 << "." << endl;
      cout << "string: " << fbxHeader.String3 << "." << endl;
      cout << "string: " << fbxHeader.String4 << "." << endl;
      cout << "string: " << fbxHeader.String5 << "." << endl;
      cout << "string: " << fbxHeader.String6 << "." << endl;
      
      
      system( "pause" );
      
      ofstream fout;
      fout.open(fileName.c_str(), ios::binary);
      fout.write((char*)(void*)&header,sizeof(SkinModelHeader));
      for (int i = 0; i < header.numMaterials; i++) {
         fout.write((char*)(void*)&materials[i], sizeof(SkinModelMaterial));
      }
      fout.write((char*)(void*)&modelData.numIndices,4);
      fout.write((char*)(void*)&modelData.numVertices,4);
      for (int i = 0; i < modelData.numIndices; i++) {
         fout.write((char*)(void*)&modelData.indices[i], 2);
      }
      for (int i = 0; i < modelData.numVertices; i++) {
         fout.write((char*)(void*)&modelData.verteces[i],sizeof(SkinModelVertex));
      }
   }

   void importSkn(string infile) {
      //import from .skn file
      ifstream fin;
      fin.open(infile.c_str(), ios::binary);
      if (fin.fail()) {
         cout << "ERROR: could not open " << infile << endl;
         system( "pause" );
         exit(1);
      }
      fin.read((char*)(void*)&header,sizeof(SkinModelHeader));
      
      cout << "Magic: " << header.magic << "." << endl;
      cout << "Version: " << header.version << "." << endl;
      cout << "Objetos: " << header.numObjects << "." << endl;
      cout << "Texturas: " << header.numMaterials<< "." << endl;
      system( "pause" );
      
      for (int i = 0; i < header.numMaterials ; i++){
         SkinModelMaterial mat;
         fin.read((char*)(void*)&mat, sizeof(SkinModelMaterial));
          cout << "Nombre: " << mat.name << "." << endl;
          //cout << "Textura indice: " << mat.matIndex<< "." << endl;
          
          cout << "startVertex: " << mat.startVertex<< "." << endl;
          cout << "numVertices: " << mat.numVertices<< "." << endl;
          cout << "startIndex: " << mat.startIndex<< "." << endl;
          cout << "numIndices: " << mat.numIndices<< "." << endl;
          system( "pause" );
         materials.push_back(mat);
       }
      fin.read((char*)(void*)&modelData.numIndices,4);
      fin.read((char*)(void*)&modelData.numVertices,4);
      cout << "indices: " << modelData.numIndices<< "." << endl;
      cout << "vertices: " << modelData.numVertices<< "." << endl;
      system( "pause" );
      
      for (int i = 0; i < modelData.numIndices; i++) {
         short idx;
         fin.read((char*)(void*)&idx, 2);
         modelData.indices.push_back(idx);
      }
      for (int i = 0; i < modelData.numVertices; i++) {
         SkinModelVertex vtx;
         fin.read((char*)(void*)&vtx,sizeof(SkinModelVertex));
         modelData.verteces.push_back(vtx);
      }
   }

   void importMesh(string infile) {
      //import from ASCII mesh output from Maya Script
      //cout << "Compiling skin file: " << infile << " to binary file: " << outfile << endl;
      ifstream fin(infile.c_str());
      if (fin.fail()) {
         cout << "ERROR: could not open " << infile << endl;
         system( "pause" );
         exit(1);
      }
      int numVerts;
      fin >> numVerts;
      modelData.numVertices = numVerts;
      for (int i = 0; i < numVerts; i++) {
         SkinModelVertex vtx;
         fin >> vtx.position[0] >> vtx.position[1] >> vtx.position[2];
         
         for (int j = 0;  j < 3; j++) {
            int boneIdx = 0;
            string boneIdxStr;
            fin >> boneIdxStr;
            if (boneIdxStr != "#NULL") {
               string tmp;
               for (int k = boneIdxStr.length() - 1; k >= 0; k--) {
                  if (boneIdxStr[k] == '_') {
                     boneIdxStr[k] = ' ';
                     break;
                  }
               }
            }
            char name[32];
            sscanf(boneIdxStr.c_str(), "%s %d",name,&boneIdx);
            vtx.boneIndex[j] = boneIdx;
            
         }
         vtx.boneIndex[3] = 0;
         fin >> vtx.weights[0] >> vtx.weights[1] >> vtx.weights[2];
         vtx.weights[3] = 0;
         //normalize weights
         float weightSum = vtx.weights[0] + vtx.weights[1] + vtx.weights[2];
         vtx.weights[0] *= 1.0f/weightSum;
         vtx.weights[1] *= 1.0f/weightSum;
         vtx.weights[2] *= 1.0f/weightSum;
         fin >> vtx.normal[0] >> vtx.normal[1] >> vtx.normal[2];
         fin >> vtx.texcoords[0] >> vtx.texcoords[1];
         vtx.texcoords[1] = 1 - vtx.texcoords[1];      //flip the UVs
         modelData.verteces.push_back(vtx);
      }
      SkinModelMaterial mat;
      memset((void*)&mat,0,sizeof(SkinModelMaterial));
      fin >> mat.name;
      int numFaces;
      fin >> numFaces;
      string nameStr = string(mat.name);
      if (nameStr != "lambert1") {
         cout << "NOTE: The material name is " << nameStr << ". Make sure this matches the same material as the original skin file!!!" << endl;
         header.numMaterials = 1;
         //mat.matIndex = 1;
         mat.numIndices = numFaces*3;
         mat.numVertices = numVerts;
         mat.startIndex = 0;
         mat.startVertex = 0;
         materials.push_back(mat);
      } else {
         cout << "WARNING: The default material was used because this model used the default material lambert1. Only do this if the original .skn file has no materials." << endl;
         header.numMaterials = 0;
      }
      header.magic = 1122867;
      header.numObjects = 1;
      modelData.numIndices = numFaces*3;
      for (int i = 0; i < numFaces; i++) {
         for (int j = 0; j < 3; j++) {
            short face;
            fin >> face;
            modelData.indices.push_back(face);
         }
      }
   }

   void importFbx(string infile) {
      //import from ASCII mesh output from Maya Script
      //cout << "Compiling skin file: " << infile << " to binary file: " << outfile << endl;
      ifstream fin(infile.c_str());
      if (fin.fail()) {
         cout << "ERROR: could not open " << infile << endl;
         system( "pause" );
         exit(1);
      }
      int numVerts;
      fin >> numVerts;
      modelData.numVertices = numVerts;
      for (int i = 0; i < numVerts; i++) {
         SkinModelVertex vtx;
         fin >> vtx.position[0] >> vtx.position[1] >> vtx.position[2];
         
         for (int j = 0;  j < 3; j++) {
            int boneIdx = 0;
            string boneIdxStr;
            fin >> boneIdxStr;
            if (boneIdxStr != "#NULL") {
               string tmp;
               for (int k = boneIdxStr.length() - 1; k >= 0; k--) {
                  if (boneIdxStr[k] == '_') {
                     boneIdxStr[k] = ' ';
                     break;
                  }
               }
            }
            char name[32];
            sscanf(boneIdxStr.c_str(), "%s %d",name,&boneIdx);
            vtx.boneIndex[j] = boneIdx;
            
         }
         vtx.boneIndex[3] = 0;
         fin >> vtx.weights[0] >> vtx.weights[1] >> vtx.weights[2];
         vtx.weights[3] = 0;
         //normalize weights
         float weightSum = vtx.weights[0] + vtx.weights[1] + vtx.weights[2];
         vtx.weights[0] *= 1.0f/weightSum;
         vtx.weights[1] *= 1.0f/weightSum;
         vtx.weights[2] *= 1.0f/weightSum;
         fin >> vtx.normal[0] >> vtx.normal[1] >> vtx.normal[2];
         fin >> vtx.texcoords[0] >> vtx.texcoords[1];
         vtx.texcoords[1] = 1 - vtx.texcoords[1];      //flip the UVs
         modelData.verteces.push_back(vtx);
      }
      SkinModelMaterial mat;
      memset((void*)&mat,0,sizeof(SkinModelMaterial));
      fin >> mat.name;
      int numFaces;
      fin >> numFaces;
      string nameStr = string(mat.name);
      if (nameStr != "lambert1") {
         cout << "NOTE: The material name is " << nameStr << ". Make sure this matches the same material as the original skin file!!!" << endl;
         header.numMaterials = 1;
         //mat.matIndex = 1;
         mat.numIndices = numFaces*3;
         mat.numVertices = numVerts;
         mat.startIndex = 0;
         mat.startVertex = 0;
         materials.push_back(mat);
      } else {
         cout << "WARNING: The default material was used because this model used the default material lambert1. Only do this if the original .skn file has no materials." << endl;
         header.numMaterials = 0;
      }
      header.magic = 1122867;
      header.numObjects = 1;
      modelData.numIndices = numFaces*3;
      for (int i = 0; i < numFaces; i++) {
         for (int j = 0; j < 3; j++) {
            short face;
            fin >> face;
            modelData.indices.push_back(face);
         }
      }
   }

   
};


void dumpSkeleton(string infile, string outfile) {
   //dump out the contents of a .skl file as ASCII for importing into Maya or some other 3d Application.
   ifstream fin;
   fin.open(infile.c_str(), ios::binary);
   if (fin.fail()) {
      cout << "ERROR: could not open " << infile << endl;
      system( "pause" );
      exit(1);
   }
   ofstream fout(outfile.c_str());
   unsigned int version;
   unsigned int bones;
   
   //estoy en esta parte
   //con false elijo el formato SklHeaderX
   //es la nueva estructura de ficheros skl
   //dejo la antigua por si se intenta abrir un archivo viejo...
   
   if (true) {
       SklHeader header;
       fin.read((char*)(void*)&header, sizeof(header));
       cout << "Found " << header.numElements << " bones" << endl;
       fout << ";;Header" << endl;
       fout << header.fileType << endl;
       fout << ";;Version " << header.version << endl;
       fout << ";;Designer ID " << header.designerID << endl;
       fout << header.numElements << endl;
       version = header.version;
       bones = header.numElements;
    } else {
          version = 0;
       SklHeaderX header;
       fin.read((char*)(void*)&header, sizeof(header));
       cout << "Found " << header.numElements << " bones" << endl;
       fout << ";;Header" << endl;
       fout << header.fileType << endl;
        fout << header.numObjects << endl;
       fout << ";;Designer ID " << header.skeletonHash << endl;
       fout << header.numElements << endl;
       bones = header.numElements;
    }
   
   fout << ";;Bones" << endl;
   
     if (version!=0) {
       for (int i = 0; i < bones; i++) {
            Bone bone;
            fin.read((char*)(void*)&bone, sizeof(Bone));
          //char lala;
          //memcpy(lala,bone.nameId,2);
          fout << bone.name << endl;
          fout << bone.parent << endl;
          fout << bone.scale << endl;
          for (int i = 0; i < 3; i++) {
             for (int j = 0; j < 4; j++) {
                fout << bone.matrix[i][j] << " ";
             }
             fout << endl;
            }
       }
    } else {
       for (int i = 0; i < bones; i++) {
          BoneX bone;
          fin.read((char*)(void*)&bone, sizeof(Bone));
          fout << bone.nameId << endl;
          fout << bone.parent << endl;
          fout << bone.scale << endl;
          for (int i = 0; i < 3; i++) {
             for (int j = 0; j < 4; j++) {
                fout << bone.matrix[i][j] << " ";
             }
             fout << endl;
            }
       }
    }
}


void compileSkeleton(string infile, string outfile) {
   //Compile the ASCII skeleton file back into a .skl file
   ifstream fin;
   fin.open(infile.c_str());
   if (fin.fail()) {
      cout << "ERROR: could not open " << infile << endl;
      system( "pause" );
      exit(1);
   }
   ofstream fout;
   fout.open(outfile.c_str(), ios::binary);
   SklHeader header;
   
   fin >> header.fileType;
   //fin >> header.numObjects;
   //fin >> header.skeletonHash;
   fin >> header.numElements;

   fout.write((const char*)&header,sizeof(SklHeader));
   for (int i = 0; i < header.numElements; i++) {
      Bone bone;
      memset(bone.name,0,32);
      fin >> bone.name;
      fin >> bone.parent;
      fin >> bone.scale;
      for (int i = 0; i < 3; i++) {
         for (int j = 0; j < 4; j++) {
            fin >> bone.matrix[i][j];
         }
      }
      fout.write((const char*)&bone, sizeof(Bone));
   }
}


int main(int argc, char *argv[]) {
   
   string cmd = string(argv[1]);
   if (cmd == "toFbx") {
            SkinModel skin;
            string file = string(argv[2]);
            skin.exportFbx(file);
            return 2;
            } else if (argc != 5) {
      cout << "Usage: lolskintool <command> <type> <inputFile> <outputFile>" << endl;
      cout << "Valid commands are: c (compile), d (decompile)" << endl;
      cout << "Supported types are: skl (skeleton), skn (skin)" << endl;
      system( "pause" );
      return 2;
   }
   string type = string(argv[2]);
   string inputFile = string(argv[3]);
   string outputFile = string(argv[4]);

   if (cmd == "compile" || cmd == "c") {
      if (type == "skl" || type == "skeleton") {
         cout << "Compiling ASCII skeleton file: " << inputFile << " to binary .skl file: " << outputFile << endl;
         compileSkeleton(inputFile, outputFile);
         cout << "Done!" << endl;
      } else if (type == "skn" || type == "skin") {
         SkinModel model;
         cout << "Compiling ASCII skin mesh file: " << inputFile << " to binary .skn file: " << outputFile << endl;
         model.importMesh(inputFile);
         model.exportSkn(outputFile);
         cout << "Done!" << endl;
      } else {
         cout << "Unsupported file type" << endl;
         return 2;
      }
   } else if (cmd == "decompile" || cmd == "d") {
      if (type == "skl" || type == "skeleton") {
         cout << "Decompiling binary .skl file: " << inputFile << " to ASCII file: " << outputFile << endl;
         dumpSkeleton(inputFile, outputFile);
         cout << "Done!" << endl;
      } else if (type == "skn" || type == "skin") {
         cout << "Decompiling binary .skn file: " << inputFile << " to .obj file: " << outputFile << endl;
         SkinModel model;
         model.importSkn(inputFile);
         model.exportObj(outputFile);
         cout << "Done!" << endl;
      } else {
         cout << "Unsupported file type" << endl;
         return 2;
      }
   } else {
      cout << "Unsupported command" << endl;
      return 2;
   }
   return 0;
}
Volver arriba Ir abajo
Ver perfil de usuario http://33.media.tumblr.com/04ce0ed37cbf34da18782f49a8b3765d/tumb
 

Ingenieria inversa League of Legends

Ver el tema anterior Ver el tema siguiente Volver arriba 
Página 1 de 1.

 Temas similares

-
» Clan Exodia - League of Legends
» JUGAIS LEAGUE OF LEGENDS ¡¡¡ESTE ES VUESTRO FORO!!!!
» Como puedo cambiar un banner (logo)?
» Fondos De League Of Legends..
» Virtual League ESMS 2012

Permisos de este foro:No puedes responder a temas en este foro.
Entidad 3D :: Creación de juegos en 3D sin programar :: Off-Topic :: Temas Varios-