Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/PojavLauncher_iOS
Path: blob/main/Natives/MinecraftResourceUtils.m
589 views
1
#include <CommonCrypto/CommonDigest.h>
2
3
#import "authenticator/BaseAuthenticator.h"
4
#import "LauncherNavigationController.h"
5
#import "LauncherPreferences.h"
6
#import "MinecraftResourceUtils.h"
7
#import "ios_uikit_bridge.h"
8
#import "utils.h"
9
10
@implementation MinecraftResourceUtils
11
12
// Handle inheritsFrom
13
+ (void)processVersion:(NSMutableDictionary *)json inheritsFrom:(NSMutableDictionary *)inheritsFrom {
14
[self insertSafety:inheritsFrom from:json arr:@[
15
@"assetIndex", @"assets", @"id",
16
@"inheritsFrom",
17
@"mainClass", @"minecraftArguments",
18
@"optifineLib", @"releaseTime", @"time", @"type"
19
]];
20
inheritsFrom[@"arguments"] = json[@"arguments"];
21
22
for (NSMutableDictionary *lib in json[@"libraries"]) {
23
NSString *libName = [lib[@"name"] substringToIndex:[lib[@"name"] rangeOfString:@":" options:NSBackwardsSearch].location];
24
int i;
25
for (i = 0; i < [inheritsFrom[@"libraries"] count]; i++) {
26
NSMutableDictionary *libAdded = inheritsFrom[@"libraries"][i];
27
NSString *libAddedName = [libAdded[@"name"] substringToIndex:[libAdded[@"name"] rangeOfString:@":" options:NSBackwardsSearch].location];
28
29
if ([libAdded[@"name"] hasPrefix:libName]) {
30
inheritsFrom[@"libraries"][i] = lib;
31
i = -1;
32
break;
33
}
34
}
35
36
if (i != -1) {
37
[inheritsFrom[@"libraries"] addObject:lib];
38
}
39
}
40
41
//inheritsFrom[@"inheritsFrom"] = nil;
42
}
43
44
+ (void)insertSafety:(NSMutableDictionary *)targetVer from:(NSDictionary *)fromVer arr:(NSArray *)arr {
45
for (NSString *key in arr) {
46
if (([fromVer[key] isKindOfClass:NSString.class] && [fromVer[key] length] > 0) || targetVer[key] == nil) {
47
targetVer[key] = fromVer[key];
48
} else {
49
NSLog(@"[MCDL] insertSafety: how to insert %@?", key);
50
}
51
}
52
}
53
54
+ (NSInteger)numberOfArgsToSkipForArg:(NSString *)arg {
55
if (![arg isKindOfClass:NSString.class]) {
56
// Skip non-string arg
57
return 1;
58
} else if ([arg hasPrefix:@"-cp"]) {
59
// Skip "-cp <classpath>"
60
return 2;
61
} else if ([arg hasPrefix:@"-Djava.library.path="]) {
62
return 1;
63
} else if ([arg hasPrefix:@"-XX:HeapDumpPath"]) {
64
return 1;
65
} else {
66
return 0;
67
}
68
}
69
70
+ (void)tweakVersionJson:(NSMutableDictionary *)json {
71
// Exclude some libraries
72
for (NSMutableDictionary *library in json[@"libraries"]) {
73
library[@"skip"] = @(
74
// Exclude platform-dependant libraries
75
library[@"downloads"][@"classifiers"] != nil ||
76
library[@"natives"] != nil ||
77
// Exclude LWJGL libraries
78
[library[@"name"] hasPrefix:@"org.lwjgl"]
79
);
80
81
NSString *versionStr = [library[@"name"] componentsSeparatedByString:@":"][2];
82
NSArray<NSString *> *version = [versionStr componentsSeparatedByString:@"."];
83
if ([library[@"name"] hasPrefix:@"net.java.dev.jna:jna:"]) {
84
// Special handling for LabyMod 1.8.9 and Forge 1.12.2(?)
85
// we have libjnidispatch 5.13.0 in Frameworks directory
86
uint32_t bundledVer = 5 << 16 | 13 << 8 | 0;
87
uint32_t requiredVer = (char)version[0].intValue << 16 | (char)version[1].intValue << 8 | (char)version[2].intValue;
88
if (requiredVer > bundledVer) {
89
NSLog(@"[MCDL] Warning: JNA version required by %@ is %@ > 5.13.0, skipping JNA replacement.", json[@"id"], versionStr);
90
continue;
91
}
92
library[@"name"] = @"net.java.dev.jna:jna:5.13.0";
93
library[@"downloads"][@"artifact"][@"path"] = @"net/java/dev/jna/jna/5.13.0/jna-5.13.0.jar";
94
library[@"downloads"][@"artifact"][@"url"] = @"https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.13.0/jna-5.13.0.jar";
95
library[@"downloads"][@"artifact"][@"sha1"] = @"1200e7ebeedbe0d10062093f32925a912020e747";
96
} else if ([library[@"name"] hasPrefix:@"org.ow2.asm:asm-all:"]) {
97
// Early versions of the ASM library get repalced with 5.0.4 because Pojav's LWJGL is compiled for
98
// Java 8, which is not supported by old ASM versions. Mod loaders like Forge, which depend on this
99
// library, often include lwjgl in their class transformations, which causes errors with old ASM versions.
100
if(version[0].intValue >= 5) continue;
101
library[@"name"] = @"org.ow2.asm:asm-all:5.0.4";
102
library[@"downloads"][@"artifact"][@"path"] = @"org/ow2/asm/asm-all/5.0.4/asm-all-5.0.4.jar";
103
library[@"downloads"][@"artifact"][@"sha1"] = @"e6244859997b3d4237a552669279780876228909";
104
library[@"downloads"][@"artifact"][@"url"] = @"https://repo1.maven.org/maven2/org/ow2/asm/asm-all/5.0.4/asm-all-5.0.4.jar";
105
}
106
}
107
108
// Add the client as a library
109
NSMutableDictionary *client = [[NSMutableDictionary alloc] init];
110
client[@"downloads"] = [[NSMutableDictionary alloc] init];
111
if (json[@"downloads"][@"client"] == nil) {
112
client[@"downloads"][@"artifact"] = [[NSMutableDictionary alloc] init];
113
client[@"skip"] = @YES;
114
} else {
115
client[@"downloads"][@"artifact"] = json[@"downloads"][@"client"];
116
}
117
client[@"downloads"][@"artifact"][@"path"] = [NSString stringWithFormat:@"../versions/%1$@/%[email protected]", json[@"id"]];
118
client[@"name"] = [NSString stringWithFormat:@"%@.jar", json[@"id"]];
119
[json[@"libraries"] addObject:client];
120
121
// Parse Forge 1.17+ additional JVM Arguments
122
if (json[@"inheritsFrom"] == nil || json[@"arguments"][@"jvm"] == nil) {
123
return;
124
}
125
json[@"arguments"][@"jvm_processed"] = [[NSMutableArray alloc] init];
126
NSDictionary *varArgMap = @{
127
@"${classpath_separator}": @":",
128
@"${library_directory}": [NSString stringWithFormat:@"%s/libraries", getenv("POJAV_GAME_DIR")],
129
@"${version_name}": json[@"id"]
130
};
131
int argsToSkip = 0;
132
for (NSString *arg in json[@"arguments"][@"jvm"]) {
133
if (argsToSkip == 0) {
134
argsToSkip = [self numberOfArgsToSkipForArg:arg];
135
}
136
if (argsToSkip == 0) {
137
NSString *argStr = arg;
138
for (NSString *key in varArgMap.allKeys) {
139
argStr = [argStr stringByReplacingOccurrencesOfString:key withString:varArgMap[key]];
140
}
141
[json[@"arguments"][@"jvm_processed"] addObject:argStr];
142
} else {
143
argsToSkip--;
144
}
145
}
146
}
147
148
+ (NSObject *)findVersion:(NSString *)version inList:(NSArray *)list {
149
return [list filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(id == %@)", version]].firstObject;
150
}
151
152
+ (NSObject *)findNearestVersion:(NSObject *)version expectedType:(int)type {
153
if (type != TYPE_RELEASE && type != TYPE_SNAPSHOT) {
154
// Only support finding for releases and snapshot for now
155
return nil;
156
}
157
158
if ([version isKindOfClass:NSString.class]){
159
// Find in inheritsFrom
160
NSDictionary *versionDict = parseJSONFromFile([NSString stringWithFormat:@"%1$s/versions/%2$@/%[email protected]", getenv("POJAV_GAME_DIR"), version]);
161
NSAssert(versionDict != nil, @"version should not be null");
162
if (versionDict[@"inheritsFrom"] == nil) {
163
// How then?
164
return nil;
165
}
166
NSObject *inheritsFrom = [self findVersion:versionDict[@"inheritsFrom"] inList:remoteVersionList];
167
if (type == TYPE_RELEASE) {
168
return inheritsFrom;
169
} else if (type == TYPE_SNAPSHOT) {
170
return [self findNearestVersion:inheritsFrom expectedType:type];
171
}
172
}
173
174
NSString *versionType = [version valueForKey:@"type"];
175
int index = [remoteVersionList indexOfObject:(NSDictionary *)version];
176
if ([versionType isEqualToString:@"release"] && type == TYPE_SNAPSHOT) {
177
// Returns the (possible) latest snapshot for the version
178
NSDictionary *result = remoteVersionList[index + 1];
179
// Sometimes, a release is followed with another release (1.16->1.16.1), go lower in this case
180
if ([result[@"type"] isEqualToString:@"release"]) {
181
return [self findNearestVersion:result expectedType:type];
182
}
183
return result;
184
} else if ([versionType isEqualToString:@"snapshot"] && type == TYPE_RELEASE) {
185
while (remoteVersionList.count > abs(index)) {
186
// In case the snapshot has yet attached to a release, perform a reverse find
187
NSDictionary *result = remoteVersionList[abs(index)];
188
// Returns the corresponding release for the snapshot, or latest release if none found
189
if ([result[@"type"] isEqualToString:@"release"]) {
190
return result;
191
}
192
// Continue to decrement, later abs() it
193
index--;
194
}
195
}
196
197
// No idea on handling everything else
198
return nil;
199
}
200
201
@end
202
203