Merge remote-tracking branch 'refs/remotes/origin/main'

This commit is contained in:
Eilionoir Tunnicliff committed 2022-07-26 21:07:06 -04:00
commit ac01590405
32 files changed
+474 -495

No files matched your search

@@ -158,6 +158,7 @@ public final class Tools
gameDir.mkdirs();
Map<String, String> varArgMap = new ArrayMap<String, String>();
varArgMap.put("auth_session", profile.accessToken); // For legacy versions of MC
varArgMap.put("auth_access_token", profile.accessToken);
varArgMap.put("auth_player_name", username);
varArgMap.put("auth_uuid", profile.profileId);
+2 -2
View File
@@ -90,7 +90,7 @@ PACKAGING = \
cp $(SOURCEDIR)/DEBIAN/postinst DEBIAN/postinst; \
ldid -S$(SOURCEDIR)/entitlements.xml Applications/PojavLauncher.app; \
cd $(OUTPUTDIR); \
fakeroot dpkg-deb -b $(OUTPUTDIR)/net.kdt.pojavlauncher.$(1)_$(VERSION)_iphoneos-arm; \
fakeroot dpkg-deb -Zxz -b $(OUTPUTDIR)/net.kdt.pojavlauncher.$(1)_$(VERSION)_iphoneos-arm; \
mkdir -p $(OUTPUTDIR)/net.kdt.pojavlauncher.$(1)-rootless_$(VERSION)_iphoneos-arm64; \
cd $(OUTPUTDIR)/net.kdt.pojavlauncher.$(1)-rootless_$(VERSION)_iphoneos-arm64; \
mkdir -p {DEBIAN,$(IOS15PREF)/{Applications,usr/share/pojavlauncher/{accounts,instances/default,Library/{Application\ Support,Caches}}}}; \
@@ -107,7 +107,7 @@ PACKAGING = \
cp $(SOURCEDIR)/DEBIAN/postinst DEBIAN/postinst; \
ldid -S$(SOURCEDIR)/entitlements.xml $(IOS15PREF)/Applications/PojavLauncher.app; \
cd $(OUTPUTDIR); \
fakeroot dpkg-deb -b $(OUTPUTDIR)/net.kdt.pojavlauncher.$(1)-rootless_$(VERSION)_iphoneos-arm64
fakeroot dpkg-deb -Zxz -b $(OUTPUTDIR)/net.kdt.pojavlauncher.$(1)-rootless_$(VERSION)_iphoneos-arm64
# Function to check directories
DIRCHECK = \
+1 -18
View File
@@ -26,7 +26,7 @@
- (void)viewDidLoad
{
[super viewDidLoad];
setViewBackgroundColor(self.view);
[self setTitle:@"About PojavLauncher"];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
@@ -40,13 +40,6 @@
[self.view addSubview:scrollView];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
// Update color mode once
if(@available(iOS 13.0, *)) {
[self traitCollectionDidChange:nil];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
// TODO: Move this into utils?
struct utsname systemInfo;
uname(&systemInfo);
@@ -125,14 +118,4 @@
[self.navigationController pushViewController:vc animated:YES];
}
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if(@available(iOS 13.0, *)) {
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.view.backgroundColor = [UIColor blackColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
}
}
@end
+2 -1
View File
@@ -1,6 +1,7 @@
#import <UIKit/UIKit.h>
@interface AccountListViewController : UITableViewController
@interface AccountListViewController: UITableViewController<UIPopoverPresentationControllerDelegate>
@property (nonatomic, copy) void (^whenDelete)(NSString* name);
@property(nonatomic, copy) void (^whenItemSelected)(NSString* name);
+8 -1
View File
@@ -58,8 +58,10 @@
}
NSDictionary *selected = self.accountList[indexPath.row];
// By default, display the saved username
cell.textLabel.text = selected[@"username"];
if ([selected[@"username"] hasPrefix:@"Demo."]) {
// Remove the prefix "Demo."
cell.textLabel.text = [selected[@"username"] substringFromIndex:5];
cell.detailTextLabel.text = NSLocalizedString(@"login.option.demo", nil);
} else if (selected[@"xboxGamertag"] == nil) {
@@ -85,7 +87,7 @@
if (editingStyle == UITableViewCellEditingStyleDelete) {
// TODO: invalidate token
NSString *str = [self.accountList objectAtIndex:indexPath.row][@"username"];
NSString *str = self.accountList[indexPath.row][@"username"];
NSFileManager *fm = [NSFileManager defaultManager];
NSString *path = [NSString stringWithFormat:@"%s/accounts/%@.json", getenv("POJAV_HOME"), str];
if (self.whenDelete != nil) {
@@ -97,4 +99,9 @@
}
}
#pragma mark - UIPopoverPresentationControllerDelegate
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
return UIModalPresentationNone;
}
@end
+3
View File
@@ -59,6 +59,7 @@ add_executable(PojavLauncher
external/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m
external/AFNetworking/UIKit+AFNetworking/AFAutoPurgingImageCache.m
external/AFNetworking/UIKit+AFNetworking/AFImageDownloader.m
external/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.m
external/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.m
main.m
@@ -87,8 +88,10 @@ add_executable(PojavLauncher
JavaGUIViewController.m
KeyboardInput.m
LauncherFAQViewController.m
LauncherMenuViewController.m
LauncherPreferences.m
LauncherPreferencesViewController.m
LauncherSplitViewController.m
LauncherViewController.m
LoginViewController.m
MinecraftResourceUtils.m
+3 -20
View File
@@ -86,19 +86,13 @@ NSMutableArray *keyCodeMap, *keyValueMap;
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithWhite:0.2 alpha:0.5];
viewController = self;
isControlModifiable = YES;
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
// Update color mode once
if(@available(iOS 13.0, *)) {
[self traitCollectionDidChange:nil];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
CGRect screenBounds = [[UIScreen mainScreen] bounds];
UIEdgeInsets insets = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets;
@@ -203,8 +197,7 @@ NSMutableArray *keyCodeMap, *keyValueMap;
}
- (void)actionMenuExit {
[self.navigationController setNavigationBarHidden:NO animated:YES];
[self.navigationController popViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)actionMenuSave {
@@ -437,16 +430,6 @@ NSMutableArray *keyCodeMap, *keyValueMap;
}
}
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if(@available(iOS 13.0, *)) {
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.view.backgroundColor = [UIColor blackColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
}
}
#pragma mark - UIPopoverPresentationControllerDelegate
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
return UIModalPresentationNone;
+2 -18
View File
@@ -69,7 +69,8 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) {
- (void)viewDidLoad
{
[super viewDidLoad];
viewController = self;
self.view.backgroundColor = UIColor.blackColor;
[self.navigationController setNavigationBarHidden:YES animated:NO];
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
@@ -95,13 +96,6 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) {
[self.view addSubview:scrollView];
// Update color mode once
if(@available(iOS 13.0, *)) {
[self traitCollectionDidChange:nil];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(surfaceOnClick:)];
tapGesture.delegate = self;
@@ -164,14 +158,4 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) {
return NO;
}
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if(@available(iOS 13.0, *)) {
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.view.backgroundColor = [UIColor blackColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
}
}
@end
+19 -100
View File
@@ -58,6 +58,9 @@ void init_loadCustomEnv() {
// Override OpenGL version to 4.1 for Zink
setenv("MESA_GL_VERSION_OVERRIDE", "4.1", 1);
// Runs JVM in a separate thread
setenv("HACK_IGNORE_START_ON_FIRST_THREAD", "1", 1);
/* Load custom env */
FILE *envFile = fopen([NSString stringWithFormat:@"%s/custom_env.txt", getenv("POJAV_HOME")].UTF8String, "r");
@@ -103,22 +106,24 @@ void init_loadCustomJvmFlags() {
}
NSString* environmentFailsafes(int minVersion) {
NSString *jvmPath = getenv("POJAV_DETECTEDJB") ? @"/usr/lib/jvm" : [NSString stringWithFormat:@"%s/jvm", getenv("BUNDLE_PATH")];
NSString *javaHome = nil;
if (getenv("POJAV_DETECTEDJB")) {
BOOL foundJava8 = [fm fileExistsAtPath:JRE8_HOME_JB];
if (!foundJava8) {
regLog("[JavaLauncher] Java 8 wasn't found on your device. Install Java 8 for more compatibility and the mod installer.");
}
if (foundJava8 && minVersion <= 8) {
javaHome = JRE8_HOME_JB;
} else if ([fm fileExistsAtPath:JRE16_HOME_JB] && minVersion <= 16) {
javaHome = JRE16_HOME_JB;
} else if ([fm fileExistsAtPath:JRE17_HOME_JB] && minVersion <= 17) {
javaHome = JRE17_HOME_JB;
}
} else if (minVersion <= 8) {
javaHome = [NSString stringWithFormat:@"%s/jre", getenv("POJAV_HOME")];
NSString *jre8Path = [NSString stringWithFormat:@"%@/java-8-openjdk", jvmPath];
NSString *jre16Path = [NSString stringWithFormat:@"%@/java-16-openjdk", jvmPath];
NSString *jre17Path = [NSString stringWithFormat:@"%@/java-17-openjdk", jvmPath];
BOOL foundJava8 = [fm fileExistsAtPath:jre8Path];
if (!foundJava8) {
regLog("[JavaLauncher] Java 8 wasn't found on your device. Install Java 8 for more compatibility and the mod installer.");
}
if (foundJava8 && minVersion <= 8) {
javaHome = jre8Path;
} else if ([fm fileExistsAtPath:jre16Path] && minVersion <= 16) {
javaHome = jre16Path;
} else if ([fm fileExistsAtPath:jre17Path] && minVersion <= 17) {
javaHome = jre17Path;
}
if (javaHome == nil) {
@@ -163,92 +168,6 @@ int launchJVM(NSString *username, id launchTarget, int width, int height, int mi
javaHome = javaHome_pre.UTF8String;
setenv("JAVA_HOME", javaHome, 1);
if (!getenv("POJAV_DETECTEDJB")) {
char src[2048], dst[2048];
// Symlink frameworks -> dylibs on jailed environment
mkdir(javaHome, 755);
// Symlink the skeleton part of JRE
sprintf((char *)src, "%s/jre/man", getenv("BUNDLE_PATH"));
sprintf((char *)dst, "%s/man", javaHome);
symlink(src, dst);
sprintf((char *)src, "%s/jre/lib", getenv("BUNDLE_PATH"));
sprintf((char *)dst, "%s/lib", javaHome);
mkdir(dst, 755);
DIR *d;
struct dirent *dir;
d = opendir(src);
assert(d);
int i = 0;
while ((dir = readdir(d)) != NULL) {
// Skip "." and ".."
if (i < 2) {
i++;
continue;
} else if (!strncmp(dir->d_name, "jli", 3)) {
sprintf((char *)dst, "%s/lib/jli", javaHome);
mkdir(dst, 755);
// libjli.dylib
sprintf((char *)src, "%s/Frameworks/libjli.dylib.framework/libjli.dylib", getenv("BUNDLE_PATH"));
sprintf((char *)dst, "%s/lib/jli/libjli.dylib", javaHome);
symlink(src, dst);
} else if (!strncmp(dir->d_name, "server", 6)) {
sprintf((char *)dst, "%s/lib/server", javaHome);
mkdir(dst, 755);
// libjsig.dylib
sprintf((char *)src, "%s/Frameworks/libjsig.dylib.framework/libjsig.dylib", getenv("BUNDLE_PATH"));
sprintf((char *)dst, "%s/lib/server/libjsig.dylib", javaHome);
symlink(src, dst);
// libjvm.dylib
sprintf((char *)src, "%s/Frameworks/libjvm.dylib.framework/libjvm.dylib", getenv("BUNDLE_PATH"));
sprintf((char *)dst, "%s/lib/server/libjvm.dylib", javaHome);
symlink(src, dst);
// Xusage.txt
sprintf((char *)src, "%s/jre/lib/server/Xusage.txt", getenv("BUNDLE_PATH"));
sprintf((char *)dst, "%s/lib/server/Xusage.txt", javaHome);
symlink(src, dst);
} else {
sprintf((char *)src, "%s/jre/lib/%s", getenv("BUNDLE_PATH"), dir->d_name);
sprintf((char *)dst, "%s/lib/%s", javaHome, dir->d_name);
symlink(src, dst);
}
}
closedir(d);
// Symlink dylibs
sprintf((char *)src, "%s/Frameworks", getenv("BUNDLE_PATH"));
d = opendir(src);
assert(d);
i = 0;
while ((dir = readdir(d)) != NULL) {
// Skip "." and ".."
if (i < 2) {
i++;
continue;
} else if (!strncmp(dir->d_name, "lib", 3) && strlen(dir->d_name) > 12) {
char *dylibName = strdup(dir->d_name);
dylibName[strlen(dylibName) - 10] = '\0';
sprintf((char *)src, "%s/Frameworks/%s/%s", getenv("BUNDLE_PATH"), dir->d_name, dylibName);
if (!strncmp(dir->d_name, "libjvm.dylib", 12)) {
sprintf((char *)dst, "%s/lib/server/%s", javaHome, dylibName);
} else {
sprintf((char *)dst, "%s/lib/%s", javaHome, dylibName);
}
symlink(src, dst);
dylibName[strlen(dylibName) - 11] = '.';
free(dylibName);
}
}
closedir(d);
}
renderer_pre = getPreference(@"renderer");
renderer = renderer_pre.UTF8String;
if (renderer_pre.length == 0) {
+1 -17
View File
@@ -12,7 +12,7 @@ CGFloat faqcurrY = 4.0;
- (void)viewDidLoad
{
[super viewDidLoad];
setViewBackgroundColor(self.view);
[self setTitle:@"Launcher FAQ"];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
@@ -25,12 +25,6 @@ CGFloat faqcurrY = 4.0;
[self.view addSubview:scrollView];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
// Update color mode once
if(@available(iOS 13.0, *)) {
[self traitCollectionDidChange:nil];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
NSString *snapheadingtext = @"Vanilla versions after 21w08b";
faqcurrY = 4.0;
@@ -67,14 +61,4 @@ CGFloat faqcurrY = 4.0;
return label;
}
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if(@available(iOS 13.0, *)) {
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.view.backgroundColor = [UIColor blackColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
}
}
@end
+7
View File
@@ -0,0 +1,7 @@
#import <UIKit/UIKit.h>
@interface LauncherMenuViewController : UITableViewController
@property NSString* listPath;
@end
+138
View File
@@ -0,0 +1,138 @@
#import "authenticator/BaseAuthenticator.h"
#import "AccountListViewController.h"
#import "LauncherMenuViewController.h"
#import "LauncherPreferencesViewController.h"
#import "LauncherViewController.h"
#import "UIButton+AFNetworking.h"
#import "UIImageView+AFNetworking.h"
@interface LauncherMenuViewController () {
}
@property NSArray<UIViewController*> *options;
@end
@implementation LauncherMenuViewController
- (void)viewDidLoad {
[super viewDidLoad];
// View controllers are put into an array to keep its state
self.options = @[
[[LauncherViewController alloc] init],
[[LauncherPreferencesViewController alloc] init]
];
self.options[0].title = @"PojavLauncher";
self.options[1].title = @"Preferences";
//@[@"News", @"Development Console", @"Crash logs"];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
UIButton *titleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[titleButton addTarget:self action:@selector(selectAccount:) forControlEvents:UIControlEventTouchUpInside];
titleButton.frame = self.navigationController.navigationBar.frame;
titleButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
if (@available(iOS 14.0, tvOS 14.0, *)) {
// On iOS 14+, a special button is displayed to toggle the visibility of the master view controller.
// It creates a bit more offset while in the process of swipe/animation. Therefore the left inset
// has to be increased a bit for this button.
titleButton.contentEdgeInsets = UIEdgeInsetsMake(4, 4, 4, 8);
} else {
titleButton.contentEdgeInsets = UIEdgeInsetsMake(4, 0, 4, 8);
}
titleButton.titleEdgeInsets = UIEdgeInsetsMake(0, 4, 0, -4);
titleButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
titleButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.navigationItem.titleView = titleButton;
[self updateAccountInfo];
[self tableView:self.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// workaround while investigating for issue
if (self.splitViewController.viewControllers.count < 2) return;
// Restore the selected row when the view appears again
int index = [self.options indexOfObject:[self.splitViewController.viewControllers[1] viewControllers][0]];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.options.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
cell.textLabel.text = [self.options[indexPath.row] title];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *selected = self.options[indexPath.row];
[self.splitViewController.viewControllers[1] setViewControllers:@[selected] animated:NO]; //YES?
if (@available(iOS 14.0, tvOS 14.0, *)) {
// It is unnecessary to put the toggle button as it is automated on iOS 14+
} else {
selected.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
selected.navigationItem.leftItemsSupplementBackButton = true;
}
// This button is placed temporarily while migrating to the new UI
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"❌" style:UIBarButtonItemStyleDone target:self.splitViewController action:@selector(dismissViewController)];
}
- (void)selectAccount:(UIButton *)sender {
AccountListViewController *vc = [[AccountListViewController alloc] init];
vc.whenItemSelected = ^void(NSString* name) {
// TODO: perform token refreshing
[BaseAuthenticator loadSavedName:name];
[self updateAccountInfo];
};
vc.modalPresentationStyle = UIModalPresentationPopover;
vc.preferredContentSize = CGSizeMake(350, 250);
UIPopoverPresentationController *popoverController = vc.popoverPresentationController;
popoverController.sourceView = sender;
popoverController.sourceRect = sender.bounds;
popoverController.permittedArrowDirections = UIPopoverArrowDirectionAny;
popoverController.delegate = vc;
[self presentViewController:vc animated:YES completion:nil];
}
- (void)updateAccountInfo {
NSDictionary *selected = BaseAuthenticator.current.authData;
BOOL isDemo = [selected[@"username"] hasPrefix:@"Demo."];
NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithString:[selected[@"username"] substringFromIndex:(isDemo?5:0)]];
id subtitle;
if (isDemo) {
// Remove the prefix "Demo."
subtitle = NSLocalizedString(@"login.option.demo", nil);
} else if (selected[@"xboxGamertag"] == nil) {
subtitle = NSLocalizedString(@"login.option.local", nil);
} else {
// Display the Xbox gamertag for online accounts
subtitle = selected[@"xboxGamertag"];
}
subtitle = [[NSAttributedString alloc] initWithString:subtitle attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:12]}];
[title appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n" attributes:nil]];
[title appendAttributedString:subtitle];
[(UIButton *)self.navigationItem.titleView setAttributedTitle:title forState:UIControlStateNormal];
NSURL *url = [NSURL URLWithString:[selected[@"profilePicURL"] stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"]];
UIImage *placeholder = [UIImage imageNamed:@"default_account_pfp"];
[(UIButton *)self.navigationItem.titleView setImageForState:UIControlStateNormal withURL:url placeholderImage:placeholder];
[((UIButton *)self.navigationItem.titleView).imageView setImageWithURL:url placeholderImage:placeholder];
}
@end
+1
View File
@@ -7,6 +7,7 @@
void loadPreferences();
id getPreference(NSString* key);
NSMutableDictionary* getDictionary(NSString *type);
int getJavaVersion(NSString* java);
int getSelectedJavaVersion();
void setDefaultValueForPref(NSMutableDictionary *dict, NSString* key, id value);
void setPreference(NSString* key, id value);
+5 -5
View File
@@ -46,21 +46,21 @@ NSMutableDictionary *getDictionary(NSString *type) {
return nil;
}
int getSelectedJavaVersion() {
NSString *java = [getPreference(@"java_home") lastPathComponent];
int getJavaVersion(NSString* java) {
if (java.length == 0) {
return 0;
} else if ([java hasPrefix:@"java-"] && [java hasSuffix:@"-openjdk"]) {
return [java substringWithRange:NSMakeRange(5, java.length - 13)].intValue;
} else if ([java isEqualToString:@"jre"]) {
// TODO for jailbroken: jre8 and jre17
return 8;
} else {
NSLog(@"FIXME: What is the Java version of %@?", java);
return 0;
}
}
int getSelectedJavaVersion() {
return getJavaVersion([getPreference(@"java_home") lastPathComponent]);
}
void setDefaultValueForPref(NSMutableDictionary *dict, NSString* key, id value) {
if (!dict[key]) {
dict[key] = value;
+17 -73
View File
@@ -84,7 +84,7 @@ UITextField *gdirTextField;
UITextField *activeField;
NSArray* rendererList;
NSMutableArray* gdirList;
NSMutableArray* jhomeList;
NSArray* jhomeList;
UIPickerView* rendPickerView;
UIPickerView* gdirPickerView;
UIPickerView* jhomePickerView;
@@ -95,15 +95,12 @@ UIScrollView *scrollView;
NSDictionary *rendererDict;
NSString *JRE8_HOME_SB;
int tempIndex;
- (void)viewDidLoad
{
[super viewDidLoad];
[self setTitle:@"Preferences"];
setViewBackgroundColor(self.view);
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
@@ -111,14 +108,7 @@ int tempIndex;
int width = (int) roundf(screenBounds.size.width);
int height = (int) roundf(screenBounds.size.height) - self.navigationController.navigationBar.frame.size.height;
CGFloat currY = 8.0;
/*
javaDict = @{
@"/usr/lib/jvm/java-8-openjdk": @"Java 8",
@"/usr/lib/jvm/java-16-openjdk": @"Java 16",
@"/usr/lib/jvm/java-17-openjdk": @"Java 17",
[NSString stringWithFormat:@"%s/jre8", getenv("POJAV_HOME")], @"Java 8 (sandbox)"
};
*/
rendererDict = @{
@"gl4es 1.1.4 - exports OpenGL 2.1": @"libgl4es_114.dylib",
@"tinygl4angle (1.17+) - exports OpenGL 3.2 (Core Profile, limited)": @"libtinygl4angle.dylib",
@@ -137,13 +127,6 @@ int tempIndex;
blur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular];
blurView = [[UIVisualEffectView alloc] initWithEffect:blur];
// Update color mode once
if(@available(iOS 13.0, *)) {
[self traitCollectionDidChange:nil];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
UILabel *btnsizeTextView = [[UILabel alloc] initWithFrame:CGRectMake(16.0, currY, 0.0, 30.0)];
btnsizeTextView.text = @"Button scale (%)";
@@ -219,8 +202,7 @@ int tempIndex;
jargsTextField.delegate = self;
jargsTextField.placeholder = @"Specify arguments...";
jargsTextField.text = (NSString *) getPreference(@"java_args");
jargsTextField.autocorrectionType = UITextAutocorrectionTypeNo
;
jargsTextField.autocorrectionType = UITextAutocorrectionTypeNo;
jargsTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
jargsTextField.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[tableView addSubview:jargsTextField];
@@ -234,6 +216,7 @@ int tempIndex;
rendTextField = [[UITextField alloc] initWithFrame:CGRectMake(buttonSizeSlider.frame.origin.x + 3, currY, width - jargsTextView.bounds.size.width - 28.0, 30)];
[rendTextField addTarget:rendTextField action:@selector(resignFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];
rendTextField.tag = TAG_REND;
rendTextField.autocorrectionType = UITextAutocorrectionTypeNo;
rendTextField.delegate = self;
rendTextField.placeholder = @"Override renderer...";
//rendTextField.text = self.rendererDict[getPreference(@"renderer")];
@@ -270,45 +253,26 @@ int tempIndex;
jhomeTextField = [[UITextField alloc] initWithFrame:CGRectMake(buttonSizeSlider.frame.origin.x + 3, currY, width - jargsTextView.bounds.size.width - 28.0, 30)];
[jhomeTextField addTarget:jhomeTextField action:@selector(resignFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];
jhomeTextField.tag = TAG_JHOME;
jhomeTextField.autocorrectionType = UITextAutocorrectionTypeNo;
jhomeTextField.delegate = self;
jhomeTextField.placeholder = @"Override Java path...";
JRE8_HOME_SB = [NSString stringWithFormat:@"%s/jre8", getenv("POJAV_HOME")];
if(getenv("POJAV_DETECTEDJB")) {
switch (getSelectedJavaVersion()) {
case 8: jhomeTextField.text = JRE8_NAME_JB; break;
case 16: jhomeTextField.text = JRE16_NAME_JB; break;
case 17: jhomeTextField.text = JRE17_NAME_JB; break;
}
} else {
jhomeTextField.text = JRE8_NAME_SB;
}
jhomeTextField.text = [getPreference(@"java_home") lastPathComponent];
jhomeTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
jhomeTextField.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[tableView addSubview:jhomeTextField];
jhomeList = [[NSMutableArray alloc] init];
if ([[NSFileManager defaultManager] fileExistsAtPath:JRE8_HOME_JB]) {
[jhomeList addObject:JRE8_NAME_JB];
}
if ([[NSFileManager defaultManager] fileExistsAtPath:JRE16_HOME_JB]) {
[jhomeList addObject:JRE16_NAME_JB];
}
if ([[NSFileManager defaultManager] fileExistsAtPath:JRE17_HOME_JB]) {
[jhomeList addObject:JRE17_NAME_JB];
}
if ([[NSFileManager defaultManager] fileExistsAtPath:JRE8_HOME_SB]) {
[jhomeList addObject:JRE8_NAME_SB];
}
NSString *listPath = getenv("POJAV_DETECTEDJB") ? @"/usr/lib/jvm" : [NSString stringWithFormat:@"%s/jvm", getenv("BUNDLE_PATH")];
jhomeList = [NSFileManager.defaultManager contentsOfDirectoryAtPath:listPath error:nil];
jhomePickerView = [[UIPickerView alloc] init];
jhomePickerView.delegate = self;
jhomePickerView.dataSource = self;
jhomePickerView.tag = TAG_PICKER_JHOME;
[jhomePickerView reloadAllComponents];
for (int i = 0; i < jhomeList.count; i++) {
if ([jhomeList[i] isEqualToString:jhomeTextField.text]) {
if ([jhomeTextField.text isEqualToString:jhomeList[i]]) {
[jhomePickerView selectRow:i inComponent:0 animated:NO];
break;
}
@@ -616,24 +580,14 @@ int tempIndex;
- (void)textFieldDidEndEditing:(UITextField *)textField {
activeField = nil;
if (textField.tag == TAG_JARGS) {
setPreference(@"java_args", textField.text);
setPreference(@"java_args", textField.text);
} else if (textField.tag == TAG_REND) {
setPreference(@"renderer", rendererDict[textField.text]);
setenv("POJAV_RENDERER", [getPreference(@"renderer") UTF8String], 1);
} else if (textField.tag == TAG_JHOME) {
if ([textField.text isEqualToString:JRE8_NAME_JB]) {
setPreference(@"java_home", JRE8_HOME_JB);
setenv("JAVA_HOME", [JRE8_HOME_JB cStringUsingEncoding:NSUTF8StringEncoding], 1);
} else if ([textField.text isEqualToString:JRE16_NAME_JB]) {
setPreference(@"java_home", JRE16_HOME_JB);
setenv("JAVA_HOME", [JRE16_HOME_JB cStringUsingEncoding:NSUTF8StringEncoding], 1);
} else if ([textField.text isEqualToString:JRE17_NAME_JB]) {
setPreference(@"java_home", JRE17_HOME_JB);
setenv("JAVA_HOME", [JRE17_HOME_JB cStringUsingEncoding:NSUTF8StringEncoding], 1);
} else if ([textField.text isEqualToString:JRE8_NAME_SB]) {
setPreference(@"java_home", JRE8_HOME_SB);
setenv("JAVA_HOME", [JRE8_HOME_SB cStringUsingEncoding:NSUTF8StringEncoding], 1);
}
NSString *listPath = getenv("POJAV_DETECTEDJB") ? @"/usr/lib/jvm" : [NSString stringWithFormat:@"%s/jvm", getenv("BUNDLE_PATH")];
setPreference(@"java_home", [NSString stringWithFormat:@"%@/%@", listPath, textField.text]);
setenv("JAVA_HOME", [getPreference(@"java_home") UTF8String], 1);
if (![textField.text containsString:JRE8_NAME_JB] && ![textField.text containsString:JRE8_NAME_SB] && [getPreference(@"java_warn") boolValue] == YES) {
UIAlertController *javaAlert = [UIAlertController alertControllerWithTitle:@"Java version is not Java 8" message:@"Minecraft versions below 1.6, modded below 1.16.4, and the mod installer will not work unless you have Java 8 installed on your device." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
@@ -1018,16 +972,6 @@ int tempIndex;
}
}
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if(@available(iOS 13.0, *)) {
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.view.backgroundColor = [UIColor blackColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
}
}
#pragma mark - UIPopoverPresentationControllerDelegate
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
return UIModalPresentationNone;
+5
View File
@@ -0,0 +1,5 @@
#import <UIKit/UIKit.h>
@interface LauncherSplitViewController : UISplitViewController
@end
+42
View File
@@ -0,0 +1,42 @@
#import "LauncherSplitViewController.h"
#import "LauncherMenuViewController.h"
#import "LauncherViewController.h"
#import "utils.h"
@interface LauncherSplitViewController () {
}
@end
@implementation LauncherSplitViewController
- (void)viewDidLoad {
[super viewDidLoad];
viewController = self;
setViewBackgroundColor(self.view);
//TODO: maximumPrimaryColumnWidth
LauncherMenuViewController *masterVc = [[LauncherMenuViewController alloc] init];
UINavigationController *detailVc = [[UINavigationController alloc] init];
self.presentsWithGesture = YES;
self.preferredDisplayMode = UISplitViewControllerDisplayModeOneBesideSecondary;
self.viewControllers = @[[[UINavigationController alloc] initWithRootViewController:masterVc], detailVc];
if (@available(iOS 14.0, tvOS 14.0, *)) {
self.preferredSplitBehavior = UISplitViewControllerSplitBehaviorTile;
}
}
- (UITraitCollection *)traitCollection {
// Allows splitting on compact-sized iPhones
UITraitCollection *collection = super.traitCollection;
UITraitCollection *horizontalCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
return [UITraitCollection traitCollectionWithTraitsFromCollections:@[collection, horizontalCollection]];
}
- (void)dismissViewController {
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
+6 -36
View File
@@ -28,8 +28,6 @@ int versionSelectedAt = 0;
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
[self setTitle:@"PojavLauncher"];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
@@ -41,13 +39,6 @@ int versionSelectedAt = 0;
[self.view addSubview:scrollView];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
// Update color mode once
if(@available(iOS 13.0, *)) {
[self traitCollectionDidChange:nil];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
UILabel *versionTextView = [[UILabel alloc] initWithFrame:CGRectMake(4.0, 4.0, 0.0, 0.0)];
versionTextView.text = @"Minecraft version: ";
versionTextView.numberOfLines = 0;
@@ -82,10 +73,8 @@ int versionSelectedAt = 0;
handler:^(__kindof UIAction * _Nonnull action) {[self enterModInstaller:self.navigationItem.rightBarButtonItem];}];
UIAction *option2 = [UIAction actionWithTitle:@"Custom controls" image:[[UIImage systemImageNamed:@"dpad.right.fill"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] identifier:nil
handler:^(__kindof UIAction * _Nonnull action) {[self enterCustomControls];}];
UIAction *option3 = [UIAction actionWithTitle:@"Preferences" image:[[UIImage systemImageNamed:@"wrench.and.screwdriver"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] identifier:nil
handler:^(__kindof UIAction * _Nonnull action) {[self enterPreferences];}];
UIMenu *menu = [UIMenu menuWithTitle:@"" image:nil identifier:nil
options:UIMenuOptionsDisplayInline children:@[option1, option2, option3]];
options:UIMenuOptionsDisplayInline children:@[option1, option2]];
self.navigationItem.rightBarButtonItem.action = nil;
self.navigationItem.rightBarButtonItem.primaryAction = nil;
self.navigationItem.rightBarButtonItem.menu = menu;
@@ -201,20 +190,18 @@ int versionSelectedAt = 0;
handler:^(UIAlertAction * _Nonnull action) {[self enterModInstaller:self.navigationItem.rightBarButtonItem];}];
UIAlertAction *option2 = [UIAlertAction actionWithTitle:@"Custom controls" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {[self enterCustomControls];}];
UIAlertAction *option3 = [UIAlertAction actionWithTitle:@"Preferences" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {[self enterPreferences];}];
fullAlert.popoverPresentationController.barButtonItem = sender;
[self presentViewController:fullAlert animated:YES completion:nil];
[fullAlert addAction:option1];
[fullAlert addAction:option2];
[fullAlert addAction:option3];
}
}
- (void)enterCustomControls {
if (![getPreference(@"customctrl_warn") boolValue]) {
CustomControlsViewController *vc = [[CustomControlsViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self presentViewController:vc animated:YES completion:nil];
return;
}
setPreference(@"customctrl_warn", @(NO));
@@ -224,8 +211,7 @@ int versionSelectedAt = 0;
alert.popoverPresentationController.sourceRect = CGRectMake(self.view.frame.size.width-10.0, 0, 10, 10);
}
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
CustomControlsViewController *vc = [[CustomControlsViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
[self enterCustomControls];
}];
[self presentViewController:alert animated:YES completion:nil];
[alert addAction:ok];
@@ -255,20 +241,15 @@ int versionSelectedAt = 0;
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
if (controller.documentPickerMode == UIDocumentPickerModeImport) {
JavaGUIViewController *vc = [[JavaGUIViewController alloc] init];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
vc.filepath = url.path;
NSLog(@"ModInstaller: launching %@", vc.filepath);
[self.navigationController pushViewController:vc animated:YES];
[self presentViewController:vc animated:YES completion:nil];
}
}
- (void)enterPreferences {
LauncherPreferencesViewController *vc = [[LauncherPreferencesViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
- (void)launchMinecraft:(UIButton *)sender {
sender.enabled = NO;
[self.navigationItem setHidesBackButton:YES animated:YES];
NSObject *object = [versionList objectAtIndex:[versionPickerView selectedRowInComponent:0]];
@@ -282,7 +263,6 @@ int versionSelectedAt = 0;
= progress;
if (stage == nil) {
sender.enabled = YES;
[self.navigationItem setHidesBackButton:NO animated:YES];
if (mainProgress != nil) {
UIKit_launchMinecraftSurfaceVC();
}
@@ -335,14 +315,4 @@ int versionSelectedAt = 0;
return NO;
}
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if(@available(iOS 13.0, *)) {
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.view.backgroundColor = [UIColor blackColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
}
}
@end
+18 -36
View File
@@ -2,27 +2,26 @@
#include <stdio.h>
#import <AuthenticationServices/AuthenticationServices.h>
#import "authenticator/BaseAuthenticator.h"
#import "AppDelegate.h"
#import "LauncherViewController.h"
#import "LoginViewController.h"
#import "AboutLauncherViewController.h"
#import "AccountListViewController.h"
#import "LauncherFAQViewController.h"
#import "LauncherPreferences.h"
#import "LauncherSplitViewController.h"
#import "LoginViewController.h"
#import "UpdateHistoryViewController.h"
#include "ios_uikit_bridge.h"
#include "utils.h"
#import "LauncherPreferences.h"
#import "ios_uikit_bridge.h"
#import "utils.h"
#define TYPE_SELECTACC 0
#define TYPE_MICROSOFT 1
#define TYPE_OFFLINE 2
#pragma mark - LoginViewController
@interface LoginViewController () <ASWebAuthenticationPresentationContextProviding, UIPopoverPresentationControllerDelegate>{
@interface LoginViewController () <ASWebAuthenticationPresentationContextProviding>{
}
@property (nonatomic, strong) ASWebAuthenticationSession *authVC;
@property (nonatomic, strong) UIActivityViewController *activityViewController;
@@ -34,12 +33,10 @@
- (void)viewDidLoad {
[super viewDidLoad];
setViewBackgroundColor(self.view);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(msaLoginCallback:) name:@"MSALoginCallback" object:nil];
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
[self.navigationItem setBackBarButtonItem:backItem];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
int width = (int) roundf(screenBounds.size.width);
@@ -50,12 +47,6 @@
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.view addSubview:scrollView];
if(@available(iOS 13.0, *)) {
[self traitCollectionDidChange:nil];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
if(getenv("POJAV_DETECTEDJB")) {
if(strcmp(getenv("POJAV_DETECTEDJB"), "Other") == 0 && [getPreference(@"jb_warn") boolValue] == YES) {
UIAlertController *jbAlert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"login.warn.title.otherjb", nil) message:NSLocalizedString(@"login.warn.message.otherjb", nil) preferredStyle:UIAlertControllerStyleAlert];
@@ -85,7 +76,7 @@
[dateFormatter setDateFormat:@"MM-dd"];
NSString* date = [dateFormatter stringFromDate:[NSDate date]];
if(@available (iOS 14.0, *)) {
if(@available(iOS 14.0, *)) {
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage systemImageNamed:@"info.circle"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] style:UIBarButtonItemStyleDone target:self action:@selector(aboutLauncher)];
UIAction *option1 = [UIAction actionWithTitle:NSLocalizedString(@"login.menu.about", nil) image:[[UIImage systemImageNamed:@"eyes.inverse"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] identifier:nil
handler:^(__kindof UIAction * _Nonnull action) {[self aboutLauncher];}];
@@ -191,16 +182,6 @@
}
}
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if (@available(iOS 13.0, *)) {
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.view.backgroundColor = [UIColor blackColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
}
}
- (void)displayProgress:(NSString *)title {
self.title = title;
UIActivityIndicatorViewStyle style;
@@ -260,10 +241,16 @@
id callback = ^(BOOL success) {
self.title = @"";
self.navigationItem.leftBarButtonItem = nil;
if (success) {
LauncherViewController *vc = [[LauncherViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
if (!success) return;
LauncherSplitViewController *splitVc;
if (@available(iOS 14.0, tvOS 14.0, *)) {
splitVc = [[LauncherSplitViewController alloc] initWithStyle:UISplitViewControllerStyleDoubleColumn];
} else {
splitVc = [[LauncherSplitViewController alloc] init];
}
splitVc.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:splitVc animated:YES completion:nil];
};
if (type == TYPE_SELECTACC) {
[auth refreshTokenWithCallback:callback];
@@ -376,7 +363,7 @@
UIPopoverPresentationController *popoverController = [vc popoverPresentationController];
[self setPopoverProperties:popoverController sender:sender];
popoverController.permittedArrowDirections = UIPopoverArrowDirectionAny;
popoverController.delegate = self;
popoverController.delegate = vc;
[self presentViewController:vc animated:YES completion:nil];
}
@@ -413,11 +400,6 @@
}
}
#pragma mark - UIPopoverPresentationControllerDelegate
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
return UIModalPresentationNone;
}
#pragma mark - ASWebAuthenticationPresentationContextProviding
- (ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session API_AVAILABLE(ios(13.0)){
return UIApplication.sharedApplication.windows.firstObject;
+4 -7
View File
@@ -39,14 +39,11 @@ static AFURLSessionManager* manager;
// Check if the account has permission to download
+ (BOOL)checkAccessWithDialog:(BOOL)show {
// for now
if ([BaseAuthenticator.current.authData[@"username"] hasPrefix:@"Demo."] || BaseAuthenticator.current.authData[@"xboxGamertag"] != nil) {
return YES;
} else {
if (show) {
showDialog(viewController, @"Error", @"Minecraft can't be legally installed when logged in with a local account. Please switch to an online account to continue.");
}
return NO;
BOOL accessible = [BaseAuthenticator.current.authData[@"username"] hasPrefix:@"Demo."] || BaseAuthenticator.current.authData[@"xboxGamertag"] != nil;
if (!accessible && show) {
showDialog(viewController, @"Error", @"Minecraft can't be legally installed when logged in with a local account. Please switch to an online account to continue.");
}
return accessible;
}
// Check SHA of the file
-1
View File
@@ -16,7 +16,6 @@
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0)) API_AVAILABLE(ios(13.0)) API_AVAILABLE(ios(13.0)){
if (@available(iOS 13.0, *)) {
UIWindowScene *windowScene = (UIWindowScene *)scene;
self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
+140 -128
View File
@@ -26,10 +26,6 @@
// #define DEBUG_VISIBLE_TEXT_FIELD
// #define DEBUG_VISIBLE_TOUCH
#define INPUT_SPACE_CHAR @" "
#define INPUT_FULL_LENGTH 40
#define INPUT_SPACE_LENGTH 20
#ifdef DEBUG_VISIBLE_TEXT_FIELD
UILabel *inputLengthView;
#endif
@@ -41,30 +37,141 @@ BOOL slideableHotbar;
// TODO: key modifiers impl
// There are private functions that we are unable to find public replacements
// (Both are found by placing breakpoints)
@interface UITextField(private)
- (NSRange)insertFilteredText:(NSString *)text;
- (id) replaceRangeWithTextWithoutClosingTyping:(UITextRange *)range replacementText:(NSString *)text;
@end
#pragma mark Class TrackedTextField
@interface TrackedTextField : UITextField
@property int lastPosition;
@property UITextPosition* lockPos;
@property int lastTextPos;
@property CGFloat lastPointX;
@end
@implementation TrackedTextField
- (void)sendMultiBackspaces:(int)times {
for (int i = 0; i < times; i++) {
CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 1, 0);
CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 0, 0);
}
}
- (void)sendText:(NSString *)text {
for (int i = 0; i < text.length; i++) {
// Directly convert unichar to jchar since both are in UTF-16 encoding.
jchar theChar = (jchar) [text characterAtIndex:i];
if (isUseStackQueueCall) {
CallbackBridge_nativeSendCharMods(theChar, 0);
} else {
CallbackBridge_nativeSendChar(theChar);
}
#ifdef DEBUG_VISIBLE_TEXT_FIELD
inputLengthView.text = [NSString stringWithFormat:@"length=%lu", self.text.length];
#endif
}
}
- (void)beginFloatingCursorAtPoint:(CGPoint)point {
[super beginFloatingCursorAtPoint:point];
self.lastPointX = point.x;
}
// Handle cursor movement in the empty space
- (void)updateFloatingCursorAtPoint:(CGPoint)point {
[super updateFloatingCursorAtPoint:point];
if (self.lastPointX == 0 || (self.lastTextPos > 0 && self.lastTextPos < self.text.length)) {
// This is handled in -[TrackedTextField closestPositionToPoint:]
return;
}
#ifdef DEBUG_VISIBLE_TEXT_FIELD
inputLengthView.text = [NSString stringWithFormat:@"updateFloatingCursorAtPoint lastPointX=%f, lastTextPos=%d\n", self.lastPointX, self.lastTextPos];
#endif
CGFloat diff = point.x - self.lastPointX;
if (ABS(diff) < 8) {
return;
}
self.lastPointX = point.x;
int key = (diff > 0) ? GLFW_KEY_DPAD_RIGHT : GLFW_KEY_DPAD_LEFT;
CallbackBridge_nativeSendKey(key, 0, 1, 0);
CallbackBridge_nativeSendKey(key, 0, 0, 0);
}
- (void)endFloatingCursor {
[super endFloatingCursor];
self.lastPointX = 0;
}
- (UITextPosition *)closestPositionToPoint:(CGPoint)point {
// Handle cursor movement between characters
UITextPosition *position = [super closestPositionToPoint:point];
int start = [self offsetFromPosition:self.beginningOfDocument toPosition:position];
if (start - self.lastPosition != 0) {
int key = (start - self.lastPosition > 0) ? GLFW_KEY_DPAD_RIGHT : GLFW_KEY_DPAD_LEFT;
if (start - self.lastTextPos != 0) {
int key = (start - self.lastTextPos > 0) ? GLFW_KEY_DPAD_RIGHT : GLFW_KEY_DPAD_LEFT;
CallbackBridge_nativeSendKey(key, 0, 1, 0);
CallbackBridge_nativeSendKey(key, 0, 0, 0);
}
self.lastPosition = start;
return [self positionFromPosition:self.beginningOfDocument offset:clamp(start, 20, self.text.length - 20)];
self.lastTextPos = start;
return position;
}
- (void)setText:(NSString *)text {
[super setText:text];
self.lockPos = [self positionFromPosition:self.beginningOfDocument offset:20];
self.selectedTextRange = [self textRangeFromPosition:self.lockPos toPosition:self.lockPos];
- (void)deleteBackward {
if (self.text.length > 1) {
// Keep the first character (a space)
[super deleteBackward];
} else {
self.text = @" ";
}
self.lastTextPos = [super offsetFromPosition:self.beginningOfDocument toPosition:self.selectedTextRange.start];
[self sendMultiBackspaces:1];
}
- (BOOL)hasText {
self.lastTextPos = MAX(self.lastTextPos, 1);
return YES;
}
// Old name: insertText
- (NSRange)insertFilteredText:(NSString *)text {
int cursorPos = [super offsetFromPosition:self.beginningOfDocument toPosition:self.selectedTextRange.start];
// This also makes sure that lastTextPos != cursorPos (text should never be empty)
if (self.lastTextPos - cursorPos == text.length) {
// Handle text markup by first deleting N amount of characters equal to the replaced text
[self sendMultiBackspaces:text.length];
}
// What else is done by past-autocomplete (insert a space after autocompletion)
// See -[TrackedTextField replaceRangeWithTextWithoutClosingTyping:replacementText:]
self.lastTextPos = cursorPos + text.length;
[self sendText:text];
NSRange range = [super insertFilteredText:text];
return range;
}
- (id) replaceRangeWithTextWithoutClosingTyping:(UITextRange *)range replacementText:(NSString *)text
{
int length = [super offsetFromPosition:range.start toPosition:range.end];
// Delete the range of needs for autocompletion
[self sendMultiBackspaces:length];
// Insert the autocompleted text
[self sendText:text];
return [super replaceRangeWithTextWithoutClosingTyping:range replacementText:text];
}
@end
@@ -113,8 +220,6 @@ BOOL slideableHotbar;
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
UIEdgeInsets insets = UIApplication.sharedApplication.windows.firstObject.safeAreaInsets;
resolutionScale = ((NSNumber *)getPreference(@"resolution")).floatValue / 100.0;
slideableHotbar = [getPreference(@"slideable_hotbar") boolValue];
@@ -222,22 +327,21 @@ self.view.frame.size.width * 0.3 - 36.0 * 0.7, self.view.frame.size.height)];
self.mousePointerView.userInteractionEnabled = NO;
[self.rootView addSubview:self.mousePointerView];
#ifndef DEBUG_VISIBLE_TEXT_FIELD
self.inputView = [[TrackedTextField alloc] initWithFrame:CGRectMake(0, -1, 1, 1)];
#else
self.inputView = [[TrackedTextField alloc] initWithFrame:CGRectMake(5 * 2 + 160.0, 5 * 2 + 30.0, 200.0, 30.0)];
self.inputView.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.5f];
self.inputView.font = [self.inputView.font fontWithSize:20];
inputLengthView = [[UILabel alloc] initWithFrame:CGRectMake(5 * 2 + 80.0, 5 * 2 + 30.0, 80.0, 30.0)];
self.inputView = [[TrackedTextField alloc] initWithFrame:CGRectMake(0, -32.0, self.view.frame.size.width, 30.0)];
#ifdef DEBUG_VISIBLE_TEXT_FIELD
inputLengthView = [[UILabel alloc] initWithFrame:CGRectMake(0, -62.0, self.view.frame.size.width, 30.0)];
inputLengthView.text = @"length=?";
inputLengthView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.6f];
[self.rootView addSubview:inputLengthView];
#endif
//self.inputView.autocorrectionType = UITextAutocorrectionTypeNo;
self.inputView.delegate = self;
self.inputView.lastPosition = 20;
[self.inputView addTarget:self action:@selector(inputViewDidChange) forControlEvents:UIControlEventEditingChanged];
if (@available(iOS 13.0, *)) {
self.inputView.backgroundColor = UIColor.secondarySystemBackgroundColor;
} else {
self.inputView.backgroundColor = UIColor.groupTableViewBackgroundColor;
}
self.inputView.font = [UIFont fontWithName:@"Menlo-Regular" size:20];
self.inputView.clearsOnBeginEditing = YES;
self.inputView.textAlignment = NSTextAlignmentCenter;
NSString *controlFilePath = [NSString stringWithFormat:@"%s/controlmap/%@", getenv("POJAV_HOME"), (NSString *)getPreference(@"default_ctrl")];
@@ -364,6 +468,9 @@ CGPoint lastCenterPoint;
self.rootView.transform = CGAffineTransformScale(CGAffineTransformIdentity, scale, scale);
self.menuView.frame = CGRectMake(self.rootView.frame.size.width, self.rootView.frame.origin.y, self.menuView.frame.size.width, self.menuView.frame.size.height);
// scale is in range of 0.7-1
// 1.1 - scale produces in range of 0.4-0.1
// result in transform scale range of 1-0.25
self.menuView.transform = CGAffineTransformScale(CGAffineTransformIdentity, (1.1-scale)*2.5, (1.1-scale)*2.5);
} else {
CGPoint velocity = [sender velocityInView:sender.view];
@@ -372,6 +479,7 @@ CGPoint lastCenterPoint;
// calculate duration to produce smooth movement
// FIXME: any better way?
CGFloat duration = fabs(self.rootView.center.x - centerX * scale) / centerX + 0.1;
duration = MIN(0.4, duration);
//(110 - MIN(100, fabs(velocity.x))) / 100
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseOut
@@ -602,7 +710,6 @@ CGPoint lastCenterPoint;
if (sender.state == UIGestureRecognizerStateRecognized) {
if (currentHotbarSlot == -1) {
self.inputView.text = INPUT_SPACE_CHAR;
inputTextLength = 0;
CallbackBridge_nativeSendMouseButton(
@@ -631,9 +738,7 @@ CGPoint lastCenterPoint;
- (void)surfaceOnHover:(UIHoverGestureRecognizer *)sender API_AVAILABLE(ios(13.0)) {
if (@available(iOS 13.0, *)) {
if (@available(iOS 14.0, *)) {
if(isGrabbing) { // Can't put into above if statement
return;
}
if (isGrabbing) return;
}
CGPoint point = [sender locationInView:self.rootView];
// NSLog(@"Mouse move!!");
@@ -666,7 +771,6 @@ CGPoint lastCenterPoint;
if (sender.state == UIGestureRecognizerStateBegan) {
self.shouldTriggerClick = NO;
if (currentHotbarSlot == -1) {
self.inputView.text = INPUT_SPACE_CHAR;
inputTextLength = 0;
CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_LEFT, 1, 0);
@@ -681,9 +785,6 @@ CGPoint lastCenterPoint;
|| sender.state == UIGestureRecognizerStateEnded)
{
if (currentHotbarSlot == -1) {
self.inputView.text = INPUT_SPACE_CHAR;
inputTextLength = 0;
CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_LEFT, 0, 0);
} else {
@@ -718,90 +819,6 @@ CallbackBridge_nativeSendKey(GLFW_KEY_Q, 0, 0, 0);
#pragma mark - Input view stuff
NSString* inputStringBefore;
int inputStringLength = INPUT_FULL_LENGTH;
-(void)inputViewDidChange {
int typedLength = (int)self.inputView.text.length - inputStringLength;
if (typedLength < 0) {
for (int i = 0; i < -typedLength; i++) {
if (self.inputView.text.length < INPUT_FULL_LENGTH) {
self.inputView.text = [@" " stringByAppendingString:self.inputView.text];
}
CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 1, 0);
CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 0, 0);
if (inputTextLength > 0) {
--inputTextLength;
}
}
#ifdef DEBUG_VISIBLE_TEXT_FIELD
inputLengthView.text = [@"length=" stringByAppendingFormat:@"%i",
inputTextLength];
#endif
} else if (typedLength > 0) {
int index = [self.inputView offsetFromPosition:self.inputView.beginningOfDocument toPosition:self.inputView.selectedTextRange.start];
NSString *newText = [self.inputView.text substringWithRange:NSMakeRange(index - typedLength, typedLength)];
int charLength = (int) [newText length];
for (int i = 0; i < charLength; i++) {
// Directly convert unichar to jchar since both are in UTF-16 encoding.
jchar theChar = (jchar) [newText characterAtIndex:i];
if (isUseStackQueueCall) {
CallbackBridge_nativeSendCharMods(theChar, /* mods */ 0);
} else {
CallbackBridge_nativeSendChar(theChar);
}
++inputTextLength;
#ifdef DEBUG_VISIBLE_TEXT_FIELD
inputLengthView.text = [@"length=" stringByAppendingFormat:@"%i",
inputTextLength];
#endif
}
inputStringBefore = self.inputView.text;
// [self.inputView.text substringFromIndex:inputTextLength - 1];
} else {
#ifdef DEBUG_VISIBLE_TEXT_FIELD
NSLog(@"Compare \"%@\" vs \"%@\"", self.inputView.text, inputStringBefore);
#endif
for (int i = 0; i < INPUT_FULL_LENGTH; i++) {
if ([self.inputView.text characterAtIndex:i] != [inputStringBefore characterAtIndex:i]) {
NSString *inputStringNow = [self.inputView.text substringFromIndex:i];
/*
self.inputView.text = [self.inputView.text substringToIndex:i];
// self notify
[self inputViewDidChange];
self.inputView.text = [self.inputView.text stringByAppendingString:inputStringNow];
// self notify
[self inputViewDidChange];
*/
for (int i2 = 0; i2 < [inputStringNow length]; i2++) {
CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 1, 0);
CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 0, 0);
}
for (int i2 = 0; i2 < [inputStringNow length]; i2++) {
CallbackBridge_nativeSendCharMods((jchar) [inputStringNow characterAtIndex:i2], /* mods */ 0);
}
break;
}
}
#ifdef DEBUG_VISIBLE_TEXT_FIELD
inputLengthView.text = @"length =";
#endif
inputStringBefore = self.inputView.text;
}
inputStringLength = (int)self.inputView.text.length;
// Reset to default value
// self.inputView.text = INPUT_SPACE_CHAR;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
CallbackBridge_nativeSendKey(GLFW_KEY_ENTER, 0, 1, 0);
CallbackBridge_nativeSendKey(GLFW_KEY_ENTER, 0, 0, 0);
@@ -823,16 +840,10 @@ int currentVisibility = 1;
if (self.inputView.isFirstResponder) {
[self.inputView resignFirstResponder];
self.inputView.alpha = 1.0f;
self.inputView.text = @"";
} else {
[self.inputView becomeFirstResponder];
// Empty the input field so that user will no longer able to select text inside.
self.inputView.text = INPUT_SPACE_CHAR;
inputStringLength = INPUT_FULL_LENGTH;
#ifndef DEBUG_VISIBLE_TEXT_FIELD
self.inputView.alpha = 0.0f;
#endif
// Insert an undeletable space
self.inputView.text = @" ";
inputTextLength = 0;
}
}
@@ -864,6 +875,7 @@ int currentVisibility = 1;
if (!held) {
CallbackBridge_nativeSendScroll(0.0, -1.0);
}
break;
case SPECIALBTN_VIRTUALMOUSE:
if (!isGrabbing && !held) {
+2 -19
View File
@@ -18,6 +18,7 @@ CGFloat uhcurrY = 4.0;
- (void)viewDidLoad
{
[super viewDidLoad];
setViewBackgroundColor(self.view);
[self setTitle:@"Update History"];
@@ -32,15 +33,8 @@ CGFloat uhcurrY = 4.0;
[self.view addSubview:scrollView];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
// Update color mode once
if(@available(iOS 13.0, *)) {
[self traitCollectionDidChange:nil];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
uhcurrY = 4.0;
[scrollView addSubview:[self uhContent:true size:25 text:@"Current version" width:width]];
[scrollView addSubview:[self uhContent:true size:20 text:[NSString stringWithFormat:@"2.1 (%s)", CONFIG_TYPE] width:width]];
[scrollView addSubview:[self uhContent:true size:17 text:@"Changes" width:width]];
@@ -136,15 +130,4 @@ CGFloat uhcurrY = 4.0;
return label;
}
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if(@available(iOS 13.0, *)) {
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.view.backgroundColor = [UIColor blackColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
}
}
@end
+1 -3
View File
@@ -80,9 +80,6 @@ void* egl_make_current(void* window);
int config_renderer;
typedef void gl4esInitialize_func();
// typedef void gl4esSwapBuffers_func();
// gl4esSwapBuffers_func *gl4esSwapBuffers;
typedef jint RegalMakeCurrent_func(EGLContext context);
// Called from JNI_OnLoad of liblwjgl_opengl, TODO: check if unused
@@ -381,6 +378,7 @@ void pojavSwapBuffers() {
case RENDERER_MTL_ANGLE: {
if (!eglSwapBuffers_p(potatoBridge.eglDisplay, potatoBridge.eglSurface)) {
if (eglGetError_p() == EGL_BAD_SURFACE) {
NSLog(@"eglSwapBuffers error 0x%x", eglGetError_p());
stopSwapBuffers = true;
closeGLFWWindow();
}
+13 -3
View File
@@ -121,9 +121,19 @@ void UIKit_launchMinecraftSurfaceVC() {
usleep(1000);
exit(0);
} else {
SurfaceViewController *vc = [[SurfaceViewController alloc] init];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[viewController.navigationController pushViewController:vc animated:YES];
id delegate = UIApplication.sharedApplication.delegate;
if (@available(iOS 13.0, *)) {
delegate = UIApplication.sharedApplication.connectedScenes.anyObject.delegate;
}
UIWindow *window = [delegate window];
[UIView animateWithDuration:0.2 animations:^{
window.alpha = 0;
} completion:^(BOOL b){
[window resignKeyWindow];
window.alpha = 1;
window.rootViewController = [[SurfaceViewController alloc] init];
[window makeKeyAndVisible];
}];
}
});
}
+3 -4
View File
@@ -17,10 +17,9 @@ void debugLog(const char *message,...)
NSLog(@"%@",[[NSString alloc] initWithFormat:[NSString stringWithUTF8String:message] arguments:args]);
va_end(args);
} else {
static BOOL debugLog_warned = NO;
if (debugLog_warned) return;
debugLog_warned = YES;
NSLog(@"WARNING!!! DEBUG LOG DISABLED");
va_list args;
va_start(args, message);
NSLog(@"%@",[[NSString alloc] initWithFormat:[NSString stringWithUTF8String:message] arguments:args]);
va_end(args);
}
}
+7 -1
View File
@@ -141,6 +141,11 @@ void init_redirectStdio() {
});
}
void init_setupAccounts() {
NSString *controlPath = [@(getenv("POJAV_HOME")) stringByAppendingPathComponent:@"accounts"];
[fm createDirectoryAtPath:controlPath withIntermediateDirectories:NO attributes:nil error:nil];
}
void init_setupCustomControls() {
NSString *controlPath = [@(getenv("POJAV_HOME")) stringByAppendingPathComponent:@"controlmap"];
[fm createDirectoryAtPath:controlPath withIntermediateDirectories:NO attributes:nil error:nil];
@@ -178,6 +183,7 @@ void init_setupMultiDir() {
[fm createDirectoryAtPath:multidirPath withIntermediateDirectories:YES attributes:nil error:nil];
[fm removeItemAtPath:lasmPath error:nil];
[fm createDirectoryAtPath:lasmPath.stringByDeletingLastPathComponent withIntermediateDirectories:YES attributes:nil error:nil];
[fm createSymbolicLinkAtPath:lasmPath withDestinationPath:multidirPath error:nil];
setenv("POJAV_GAME_DIR", lasmPath.UTF8String, 1);
@@ -230,7 +236,7 @@ int main(int argc, char * argv[]) {
loadPreferences();
init_setupMultiDir();
init_setupLauncherProfiles();
init_setupAccounts();
init_setupCustomControls();
init_migrateToPlist("selected_version", "config_ver.txt");
+5
View File
@@ -44,6 +44,11 @@ int hooked_dladdr(const void* addr, Dl_info* info) {
}
void* hooked_dlopen(const char* path, int mode) {
// Avoid loading the executable itself twice
if (path && [@(path) hasSuffix:@"PojavLauncher"]) {
return orig_dlopen(NULL, mode);
}
void *handle = orig_dlopen(path, mode);
if (handle) {
return handle;
@@ -9,7 +9,7 @@
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string></string>
<string>dylib.java.libjnidispatch</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
@@ -9,7 +9,7 @@
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string></string>
<string>dylib.mesa3d.libvirgl_test_server</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
+1
View File
@@ -64,6 +64,7 @@ CGFloat MathUtils_dist(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2);
CGFloat MathUtils_map(CGFloat x, CGFloat in_min, CGFloat in_max, CGFloat out_min, CGFloat out_max);
CGFloat dpToPx(CGFloat dp);
CGFloat pxToDp(CGFloat px);
void setViewBackgroundColor(UIView* view);
void _CGDataProviderReleaseBytePointerCallback(void *info,const void *pointer);
jboolean attachThread(bool isAndroid, JNIEnv** secondJNIEnvPtr);
+15
View File
@@ -8,6 +8,13 @@
#include "utils.h"
// This forces the navigation bar to keep its height (44dp) in landscape
@implementation UINavigationBar(forceFullHeightInLandscape)
- (BOOL)forceFullHeightInLandscape {
return YES;
}
@end
NSMutableDictionary* parseJSONFromFile(NSString *path) {
NSError *error;
@@ -102,6 +109,14 @@ CGFloat pxToDp(CGFloat px) {
return px / screenScale;
}
void setViewBackgroundColor(UIView* view) {
if(@available(iOS 13.0, *)) {
view.backgroundColor = UIColor.systemBackgroundColor;
} else {
view.backgroundColor = UIColor.whiteColor;
}
}
jstring convertStringJVM(JNIEnv* srcEnv, JNIEnv* dstEnv, jstring srcStr) {
if (srcStr == NULL) {
return NULL;