Port minecraft.jar version detection to Qt

This commit is contained in:
Orochimarufan 2013-02-24 17:06:00 +01:00
parent ad70e3fd4c
commit ce867d9169
3 changed files with 101 additions and 66 deletions

View File

@ -7,7 +7,7 @@ namespace java
class constant class constant
{ {
public: public:
enum type_t:uint8_t enum type_t : uint8_t
{ {
j_hole = 0, // HACK: this is a hole in the array, because java is crazy j_hole = 0, // HACK: this is a hole in the array, because java is crazy
j_string_data = 1, j_string_data = 1,
@ -22,6 +22,7 @@ namespace java
j_interface_methodref = 11, j_interface_methodref = 11,
j_nameandtype = 12 j_nameandtype = 12
} type; } type;
constant(util::membuffer & buf ) constant(util::membuffer & buf )
{ {
buf.read(type); buf.read(type);
@ -66,10 +67,12 @@ namespace java
break; break;
} }
} }
constant(int fake) constant(int fake)
{ {
type = j_hole; type = j_hole;
} }
std::string toString() std::string toString()
{ {
std::ostringstream ss; std::ostringstream ss;
@ -142,7 +145,8 @@ namespace java
uint16_t descriptor_index; uint16_t descriptor_index;
} name_and_type; } name_and_type;
}; };
}; };
/** /**
* A helper class that represents the custom container used in Java class file for storage of constants * A helper class that represents the custom container used in Java class file for storage of constants
*/ */
@ -181,7 +185,7 @@ namespace java
index++; index++;
} }
} }
}; }
typedef std::vector<java::constant> container_type; typedef std::vector<java::constant> container_type;
/** /**
* Access constants based on jar file index numbers (index of the first element is 1) * Access constants based on jar file index numbers (index of the first element is 1)
@ -204,5 +208,5 @@ namespace java
} }
private: private:
container_type constants; container_type constants;
}; };
} }

View File

@ -1,69 +1,81 @@
/* Copyright 2013 MultiMC Contributors
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "multimc_pragma.h" #include "multimc_pragma.h"
#include "classfile.h" #include "classfile.h"
#include "javautils.h" #include "javautils.h"
//#include <wx/zipstrm.h>
#include <memory> #include <QFile>
//#include <wx/wfstream.h> #include <quazipfile.h>
//#include "mcversionlist.h"
namespace javautils namespace javautils
{ {
QString GetMinecraftJarVersion(QString jar)
QString GetMinecraftJarVersion(QString jarName)
{ {
return "Unknown"; QString version = MCVer_Unknown;
/*
wxString fullpath = jar.GetFullPath();
wxString version = MCVer_Unknown;
if(!jar.FileExists())
return version;
std::auto_ptr<wxZipEntry> entry;
// convert the local name we are looking for into the internal format
wxString name = wxZipEntry::GetInternalName("net/minecraft/client/Minecraft.class",wxPATH_UNIX);
// open the zip // check if minecraft.jar exists
wxFFileInputStream inStream(jar.GetFullPath()); QFile jar(jarName);
wxZipInputStream zipIn(inStream); if (!jar.exists())
return version;
// call GetNextEntry() until the required internal name is found // open minecraft.jar
do QuaZip zip(&jar);
{ if (!zip.open(QuaZip::mdUnzip))
entry.reset(zipIn.GetNextEntry()); return version;
}
while (entry.get() != NULL && entry->GetInternalName() != name);
auto myentry = entry.get();
if (myentry == NULL)
return version;
// we got the entry, read the data // open Minecraft.class
std::size_t size = myentry->GetSize(); zip.setCurrentFile("net/minecraft/client/Minecraft.class", QuaZip::csSensitive);
char *classdata = new char[size]; QuaZipFile Minecraft(&zip);
zipIn.Read(classdata,size); if (!Minecraft.open(QuaZipFile::ReadOnly))
try return version;
{
char * temp = classdata; // read Minecraft.class
java::classfile Minecraft_jar(temp,size); qint64 size = Minecraft.size();
auto cnst = Minecraft_jar.constants; char *classfile = new char[size];
auto iter = cnst.begin(); Minecraft.read(classfile, size);
while (iter != cnst.end())
{ // parse Minecraft.class
const java::constant & constant = *iter; try {
if(constant.type != java::constant::j_string_data) char *temp = classfile;
{ java::classfile MinecraftClass(temp, size);
iter++; java::constant_pool constants = MinecraftClass.constants;
continue; for(java::constant_pool::container_type::const_iterator iter=constants.begin();
} iter != constants.end(); iter++)
auto & str = constant.str_data; {
const char * lookfor = "Minecraft Minecraft "; // length = 20 const java::constant & constant = *iter;
if(str.compare(0,20,lookfor) == 0) if (constant.type != java::constant::j_string_data)
{ continue;
version = str.substr(20).data(); const std::string & str = constant.str_data;
break; if (str.compare(0, 20, "Minecraft Minecraft ") == 0)
} {
iter++; version = str.substr(20).data();
} break;
} catch(java::classfile_exception &){} }
delete[] classdata; }
return version; } catch(java::classfile_exception &) {}
*/
// clean up
delete[] classfile;
Minecraft.close();
zip.close();
jar.close();
return version;
} }
} }

View File

@ -1,9 +1,28 @@
/* Copyright 2013 MultiMC Contributors
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once #pragma once
#include <QString> #include <QString>
#define MCVer_Unknown "Unknown"
namespace javautils namespace javautils
{ {
/* /**
* Get the version from a minecraft.jar by parsing its class files. Expensive! * @brief Get the version from a minecraft.jar by parsing its class files. Expensive!
*/ */
QString GetMinecraftJarVersion(QString jar); QString GetMinecraftJarVersion(QString jar);
} }