Merge remote-tracking branch 'refs/remotes/origin/main'
This commit is contained in:
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);
|
||||
|
||||
@@ -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 = \
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,7 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface LauncherMenuViewController : UITableViewController
|
||||
|
||||
@property NSString* listPath;
|
||||
|
||||
@end
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface LauncherSplitViewController : UISplitViewController
|
||||
|
||||
@end
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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");
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user