aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--CMakeLists.txt132
-rw-r--r--config.h.in17
-rw-r--r--java/annotations.cpp83
-rw-r--r--java/annotations.h252
-rw-r--r--java/classfile.h153
-rw-r--r--java/constants.h208
-rw-r--r--java/endian.h62
-rw-r--r--java/errors.h6
-rw-r--r--java/javautils.cpp69
-rw-r--r--java/javautils.h9
-rw-r--r--java/membuffer.h64
-rw-r--r--java/test.cpp35
-rw-r--r--launcher/CMakeLists.txt23
-rw-r--r--launcher/MCFrame.java123
-rw-r--r--launcher/MultiMCLauncher.java331
-rw-r--r--launcher/UseJava.cmake881
-rw-r--r--launcher/UseJavaClassFilelist.cmake52
-rw-r--r--launcher/UseJavaSymlinks.cmake32
-rw-r--r--launcher/net/minecraft/Launcher.java154
-rw-r--r--launcher/org/simplericity/macify/eawt/Application.java176
-rw-r--r--launcher/org/simplericity/macify/eawt/ApplicationAdapter.java48
-rw-r--r--launcher/org/simplericity/macify/eawt/ApplicationEvent.java25
-rw-r--r--launcher/org/simplericity/macify/eawt/ApplicationListener.java27
-rw-r--r--launcher/org/simplericity/macify/eawt/DefaultApplication.java418
-rw-r--r--multimc.qrc57
-rw-r--r--multimc_pragma.h49
-rw-r--r--patchlib/CMakeLists.txt14
-rw-r--r--patchlib/LICENSE-bzip242
-rw-r--r--patchlib/blocksort.c1095
-rw-r--r--patchlib/bspatch.c303
-rw-r--r--patchlib/bspatch.h27
-rw-r--r--patchlib/bzlib.c1579
-rw-r--r--patchlib/bzlib.h283
-rw-r--r--patchlib/bzlib_private.h510
-rw-r--r--patchlib/compress.c672
-rw-r--r--patchlib/crctable.c104
-rw-r--r--patchlib/decompress.c646
-rw-r--r--patchlib/huffman.c205
-rw-r--r--patchlib/randtable.c84
-rw-r--r--quazip/CMakeLists.txt26
-rw-r--r--quazip/JlCompress.cpp469
-rw-r--r--quazip/JlCompress.h114
-rw-r--r--quazip/crypt.h135
-rw-r--r--quazip/ioapi.h77
-rw-r--r--quazip/qioapi.cpp146
-rw-r--r--quazip/quaadler32.cpp28
-rw-r--r--quazip/quaadler32.h29
-rw-r--r--quazip/quachecksum32.h54
-rw-r--r--quazip/quacrc32.cpp28
-rw-r--r--quazip/quacrc32.h26
-rw-r--r--quazip/quagzipfile.cpp141
-rw-r--r--quazip/quagzipfile.h35
-rw-r--r--quazip/quaziodevice.cpp283
-rw-r--r--quazip/quaziodevice.h27
-rw-r--r--quazip/quazip.cpp554
-rw-r--r--quazip/quazip.h411
-rw-r--r--quazip/quazip_global.h55
-rw-r--r--quazip/quazipdir.cpp507
-rw-r--r--quazip/quazipdir.h171
-rw-r--r--quazip/quazipfile.cpp488
-rw-r--r--quazip/quazipfile.h442
-rw-r--r--quazip/quazipfileinfo.h66
-rw-r--r--quazip/quazipnewinfo.cpp51
-rw-r--r--quazip/quazipnewinfo.h102
-rw-r--r--quazip/unzip.c1603
-rw-r--r--quazip/unzip.h356
-rw-r--r--quazip/zip.c1281
-rw-r--r--quazip/zip.h245
69 files changed, 16978 insertions, 27 deletions
diff --git a/.gitignore b/.gitignore
index 085e8baf..529735db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,6 @@
Thumbs.db
+.kdev4
+MultiMC5.kdev4
+build
+resources/CMakeFiles
+resources/MultiMCLauncher.jar
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 00000000..45f1ddb0
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,132 @@
+cmake_minimum_required(VERSION 2.8.9)
+project(multimc5)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+
+#### Check for machine endianness ####
+INCLUDE(TestBigEndian)
+TEST_BIG_ENDIAN(BIGENDIAN)
+IF(${BIGENDIAN})
+ ADD_DEFINITIONS(-DMULTIMC_BIG_ENDIAN)
+ENDIF(${BIGENDIAN})
+
+
+#### Find the required Qt parts ####
+find_package(Qt5Widgets)
+#find_package(Qt5Declarative)
+
+include_directories(${Qt5Widgets_INCLUDE_DIRS})
+
+# find ZLIB for quazip
+find_package(ZLIB REQUIRED)
+
+# Find boost.
+set(Boost_USE_STATIC_LIBS ON)
+MESSAGE(STATUS "** Finding Boost...")
+find_package(Boost 1.46.0 REQUIRED)
+MESSAGE(STATUS "** Boost Include: ${Boost_INCLUDE_DIR}")
+MESSAGE(STATUS "** Boost Libraries: ${Boost_LIBRARY_DIRS}")
+
+# Include boost.
+include_directories("${Boost_INCLUDE_DIRS}")
+
+# Add quazip
+add_subdirectory(quazip)
+
+# Add bspatch
+add_subdirectory(patchlib)
+include_directories(patchlib)
+
+# add the java launcher
+add_subdirectory(launcher)
+
+IF(UNIX)
+ # assume GCC, add C++0x/C++11 stuff
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+ELSEIF(MINGW)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
+ENDIF()
+
+# Set the path where CMake will look for modules.
+set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}")
+
+
+set(MultiMC_VERSION_MAJOR 5)
+set(MultiMC_VERSION_MINOR 0)
+set(MultiMC_VERSION_REV 0)
+
+SET(MultiMC_VERSION_BUILD 0 CACHE STRING "Build number.")
+message(STATUS "MultiMC build #${MultiMC_VERSION_BUILD}")
+
+IF (DEFINED MultiMC_BUILD_TAG)
+ message(STATUS "Build tag: ${MultiMC_BUILD_TAG}")
+ELSE ()
+ message(STATUS "No build tag specified.")
+ENDIF ()
+
+if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+ set (MultiMC_ARCH "x64"
+ CACHE STRING "Architecture we're building for.")
+else()
+ set (MultiMC_ARCH "x86"
+ CACHE STRING "Architecture we're building for.")
+endif()
+message (STATUS "Architecture is ${MultiMC_ARCH}")
+
+SET(MultiMC_Extra_Label "")
+
+IF (WIN32)
+ SET(MultiMC_JOB_NAME "MultiMC4Windows" CACHE STRING "Jenkins job name.")
+ELSEIF(UNIX AND APPLE)
+ SET(MultiMC_JOB_NAME "MultiMC4OSX" CACHE STRING "Jenkins job name.")
+ # This is here because the scheme doesn't exactly apply to every kind of build...
+ SET(MultiMC_Extra_Label ",label=osx")
+ELSE()
+ SET(MultiMC_JOB_NAME "MultiMC4Linux" CACHE STRING "Jenkins job name.")
+ENDIF()
+
+SET(MultiMC_JOB_URL "http://ci.forkk.net/job/${MultiMC_JOB_NAME}/arch=${MultiMC_ARCH}${MultiMC_Extra_Label}/"
+ CACHE STRING "URL of the jenkins job to pull updates from.")
+message(STATUS "Job URL: ${MultiMC_JOB_URL}")
+
+configure_file("${PROJECT_SOURCE_DIR}/config.h.in"
+ "${PROJECT_BINARY_DIR}/config.h")
+
+
+SET(MULTIMC_SOURCES
+main.cpp
+gui/mainwindow.cpp
+data/instancebase.cpp
+util/pathutils.cpp
+
+java/javautils.cpp
+java/annotations.cpp
+)
+
+SET(MULTIMC_HEADERS
+gui/mainwindow.h
+data/instancebase.h
+util/pathutils.h
+multimc_pragma.h
+
+java/annotations.h
+java/classfile.h
+java/constants.h
+java/endian.h
+java/errors.h
+java/javautils.h
+java/membuffer.h
+)
+
+SET_SOURCE_FILES_PROPERTIES(resources/MultiMCLauncher.jar GENERATED)
+
+QT5_WRAP_UI(MULTIMC_UI gui/mainwindow.ui)
+QT5_ADD_RESOURCES(MULTIMC_QRC multimc.qrc)
+
+add_executable(multimc5 ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC})
+qt5_use_modules(multimc5 Widgets)
+link_libraries(multimc5 quazip patchlib)
+add_dependencies(multimc5 MultiMCLauncher)
+install(TARGETS multimc5 RUNTIME DESTINATION bin)
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 00000000..de53ac93
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,17 @@
+#define VERSION_MAJOR @MultiMC_VERSION_MAJOR@
+#define VERSION_MINOR @MultiMC_VERSION_MINOR@
+#define VERSION_REVISION @MultiMC_VERSION_REV@
+#define VERSION_BUILD @MultiMC_VERSION_BUILD@
+
+#define VERSION_STR "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_REV@.@MultiMC_VERSION_BUILD@"
+
+#define x86 1
+#define x64 2
+
+#define ARCH @MultiMC_ARCH@
+
+#define JENKINS_BUILD_TAG "@MultiMC_BUILD_TAG@"
+
+#define JENKINS_JOB_URL "@MultiMC_JOB_URL@"
+
+#define USE_HTTPS @MultiMC_USE_HTTPS@
diff --git a/java/annotations.cpp b/java/annotations.cpp
new file mode 100644
index 00000000..fc0c98fa
--- /dev/null
+++ b/java/annotations.cpp
@@ -0,0 +1,83 @@
+#include "classfile.h"
+#include "annotations.h"
+#include <sstream>
+
+namespace java
+{
+ std::string annotation::toString()
+ {
+ std::ostringstream ss;
+ ss << "Annotation type : " << type_index << " - " << pool[type_index].str_data << std::endl;
+ ss << "Contains " << name_val_pairs.size() << " pairs:" << std::endl;
+ for(unsigned i = 0; i < name_val_pairs.size(); i++)
+ {
+ std::pair<uint16_t, element_value *> &val = name_val_pairs[i];
+ auto name_idx = val.first;
+ ss << pool[name_idx].str_data << "(" << name_idx << ")" << " = " << val.second->toString() << std::endl;
+ }
+ return ss.str();
+ }
+
+ annotation * annotation::read (util::membuffer& input, constant_pool& pool)
+ {
+ uint16_t type_index = 0;
+ input.read_be(type_index);
+ annotation * ann = new annotation(type_index,pool);
+
+ uint16_t num_pairs = 0;
+ input.read_be(num_pairs);
+ while(num_pairs)
+ {
+ uint16_t name_idx = 0;
+ // read name index
+ input.read_be(name_idx);
+ auto elem = element_value::readElementValue(input,pool);
+ // read value
+ ann->add_pair(name_idx, elem);
+ num_pairs --;
+ }
+ return ann;
+ }
+
+ element_value* element_value::readElementValue ( util::membuffer& input, java::constant_pool& pool )
+ {
+ element_value_type type = INVALID;
+ input.read(type);
+ uint16_t index = 0;
+ uint16_t index2 = 0;
+ std::vector <element_value *> vals;
+ switch (type)
+ {
+ case PRIMITIVE_BYTE:
+ case PRIMITIVE_CHAR:
+ case PRIMITIVE_DOUBLE:
+ case PRIMITIVE_FLOAT:
+ case PRIMITIVE_INT:
+ case PRIMITIVE_LONG:
+ case PRIMITIVE_SHORT:
+ case PRIMITIVE_BOOLEAN:
+ case STRING:
+ input.read_be(index);
+ return new element_value_simple(type, index, pool);
+ case ENUM_CONSTANT:
+ input.read_be(index);
+ input.read_be(index2);
+ return new element_value_enum(type, index, index2, pool);
+ case CLASS: // Class
+ input.read_be(index);
+ return new element_value_class(type, index, pool);
+ case ANNOTATION: // Annotation
+ // FIXME: runtime visibility info needs to be passed from parent
+ return new element_value_annotation(ANNOTATION, annotation::read(input, pool), pool);
+ case ARRAY: // Array
+ input.read_be(index);
+ for (int i = 0; i < index; i++)
+ {
+ vals.push_back(element_value::readElementValue(input, pool));
+ }
+ return new element_value_array(ARRAY, vals, pool);
+ default:
+ throw new java::classfile_exception();
+ }
+ }
+} \ No newline at end of file
diff --git a/java/annotations.h b/java/annotations.h
new file mode 100644
index 00000000..b115dc0b
--- /dev/null
+++ b/java/annotations.h
@@ -0,0 +1,252 @@
+#pragma once
+#include "classfile.h"
+#include <map>
+#include <vector>
+
+namespace java
+{
+ enum element_value_type : uint8_t
+ {
+ INVALID = 0,
+ STRING = 's',
+ ENUM_CONSTANT = 'e',
+ CLASS = 'c',
+ ANNOTATION = '@',
+ ARRAY = '[', // one array dimension
+ PRIMITIVE_INT = 'I', // integer
+ PRIMITIVE_BYTE = 'B', // signed byte
+ PRIMITIVE_CHAR = 'C', // Unicode character code point in the Basic Multilingual Plane, encoded with UTF-16
+ PRIMITIVE_DOUBLE = 'D', // double-precision floating-point value
+ PRIMITIVE_FLOAT = 'F', // single-precision floating-point value
+ PRIMITIVE_LONG = 'J', // long integer
+ PRIMITIVE_SHORT = 'S', // signed short
+ PRIMITIVE_BOOLEAN = 'Z' // true or false
+ };
+ /**
+ * The element_value structure is a discriminated union representing the value of an element-value pair.
+ * It is used to represent element values in all attributes that describe annotations
+ * - RuntimeVisibleAnnotations
+ * - RuntimeInvisibleAnnotations
+ * - RuntimeVisibleParameterAnnotations
+ * - RuntimeInvisibleParameterAnnotations).
+ *
+ * The element_value structure has the following format:
+ */
+ class element_value
+ {
+ protected:
+ element_value_type type;
+ constant_pool & pool;
+
+ public:
+ element_value(element_value_type type, constant_pool & pool): type(type), pool(pool) {};
+
+ element_value_type getElementValueType()
+ {
+ return type;
+ }
+
+ virtual std::string toString() = 0;
+
+ static element_value * readElementValue(util::membuffer & input, constant_pool & pool);
+ };
+
+ /**
+ * Each value of the annotations table represents a single runtime-visible annotation on a program element.
+ * The annotation structure has the following format:
+ */
+ class annotation
+ {
+ public:
+ typedef std::vector< std::pair<uint16_t, element_value * > > value_list;
+ protected:
+ /**
+ * The value of the type_index item must be a valid index into the constant_pool table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
+ * representing a field descriptor representing the annotation type corresponding
+ * to the annotation represented by this annotation structure.
+ */
+ uint16_t type_index;
+ /**
+ * map between element_name_index and value.
+ *
+ * The value of the element_name_index item must be a valid index into the constant_pool table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure representing
+ * a valid field descriptor (§4.3.2) that denotes the name of the annotation type element represented
+ * by this element_value_pairs entry.
+ */
+ value_list name_val_pairs;
+ /**
+ * Reference to the parent constant pool
+ */
+ constant_pool & pool;
+ public:
+ annotation(uint16_t type_index, constant_pool& pool):type_index(type_index), pool(pool) {};
+ ~annotation()
+ {
+ for(unsigned i = 0 ; i < name_val_pairs.size(); i++)
+ {
+ delete name_val_pairs[i].second;
+ }
+ }
+ void add_pair(uint16_t key, element_value * value)
+ {
+ name_val_pairs.push_back(std::make_pair(key, value));
+ };
+ value_list::const_iterator begin()
+ {
+ return name_val_pairs.cbegin();
+ }
+ value_list::const_iterator end()
+ {
+ return name_val_pairs.cend();
+ }
+ std::string toString();
+ static annotation * read(util::membuffer & input, constant_pool & pool);
+ };
+ typedef std::vector<annotation *> annotation_table;
+
+
+ /// type for simple value annotation elements
+ class element_value_simple : public element_value
+ {
+ protected:
+ /// index of the constant in the constant pool
+ uint16_t index;
+ public:
+ element_value_simple(element_value_type type, uint16_t index , constant_pool& pool):
+ element_value(type, pool), index(index)
+ {
+ // TODO: verify consistency
+ };
+ uint16_t getIndex()
+ {
+ return index;
+ }
+ virtual std::string toString()
+ {
+ return pool[index].toString();
+ };
+ };
+ /// The enum_const_value item is used if the tag item is 'e'.
+ class element_value_enum : public element_value
+ {
+ protected:
+ /**
+ * The value of the type_name_index item must be a valid index into the constant_pool table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
+ * representing a valid field descriptor (§4.3.2) that denotes the internal form of the binary
+ * name (§4.2.1) of the type of the enum constant represented by this element_value structure.
+ */
+ uint16_t typeIndex;
+ /**
+ * The value of the const_name_index item must be a valid index into the constant_pool table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
+ * representing the simple name of the enum constant represented by this element_value structure.
+ */
+ uint16_t valueIndex;
+ public:
+ element_value_enum(element_value_type type, uint16_t typeIndex, uint16_t valueIndex, constant_pool& pool):
+ element_value(type, pool), typeIndex(typeIndex), valueIndex(valueIndex)
+ {
+ // TODO: verify consistency
+ }
+ uint16_t getValueIndex()
+ {
+ return valueIndex;
+ }
+ uint16_t getTypeIndex()
+ {
+ return typeIndex;
+ }
+ virtual std::string toString()
+ {
+ return "enum value";
+ };
+ };
+
+ class element_value_class : public element_value
+ {
+ protected:
+ /**
+ * The class_info_index item must be a valid index into the constant_pool table.
+ * The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
+ * representing the return descriptor (§4.3.3) of the type that is reified by the class
+ * represented by this element_value structure.
+ *
+ * For example, 'V' for Void.class, 'Ljava/lang/Object;' for Object, etc.
+ *
+ * Or in plain english, you can store type information in annotations. Yay.
+ */
+ uint16_t classIndex;
+ public:
+ element_value_class(element_value_type type, uint16_t classIndex, constant_pool& pool):
+ element_value(type, pool), classIndex(classIndex)
+ {
+ // TODO: verify consistency
+ }
+ uint16_t getIndex()
+ {
+ return classIndex;
+ }
+ virtual std::string toString()
+ {
+ return "class";
+ };
+ };
+
+ /// nested annotations... yay
+ class element_value_annotation : public element_value
+ {
+ private:
+ annotation * nestedAnnotation;
+ public:
+ element_value_annotation(element_value_type type, annotation * nestedAnnotation, constant_pool& pool):
+ element_value(type, pool), nestedAnnotation(nestedAnnotation)
+ {};
+ ~element_value_annotation()
+ {
+ if(nestedAnnotation)
+ {
+ delete nestedAnnotation;
+ nestedAnnotation = nullptr;
+ }
+ }
+ virtual std::string toString()
+ {
+ return "nested annotation";
+ };
+ };
+
+ /// and arrays!
+ class element_value_array : public element_value
+ {
+ public:
+ typedef std::vector <element_value *> elem_vec;
+ protected:
+ elem_vec values;
+ public:
+ element_value_array ( element_value_type type, std::vector <element_value *>& values, constant_pool& pool ):
+ element_value(type, pool), values(values)
+ {};
+ ~element_value_array ()
+ {
+ for(unsigned i = 0; i < values.size();i++)
+ {
+ delete values[i];
+ }
+ };
+ elem_vec::const_iterator begin()
+ {
+ return values.cbegin();
+ }
+ elem_vec::const_iterator end()
+ {
+ return values.cend();
+ }
+ virtual std::string toString()
+ {
+ return "array";
+ };
+ };
+} \ No newline at end of file
diff --git a/java/classfile.h b/java/classfile.h
new file mode 100644
index 00000000..33207e99
--- /dev/null
+++ b/java/classfile.h
@@ -0,0 +1,153 @@
+#pragma once
+#include "membuffer.h"
+#include "constants.h"
+#include "annotations.h"
+#include <map>
+namespace java
+{
+ /**
+ * Class representing a Java .class file
+ */
+ class classfile : public util::membuffer
+ {
+ public:
+ classfile(char * data, std::size_t size) : membuffer(data, size)
+ {
+ valid = false;
+ is_synthetic = false;
+ read_be(magic);
+ if(magic != 0xCAFEBABE)
+ throw new classfile_exception();
+ read_be(minor_version);
+ read_be(major_version);
+ constants.load(*this);
+ read_be(access_flags);
+ read_be(this_class);
+ read_be(super_class);
+
+ // Interfaces
+ uint16_t iface_count = 0;
+ read_be(iface_count);
+ while (iface_count)
+ {
+ uint16_t ifac