2024-04-28 11:41:57 +08:00
|
|
|
|
//
|
|
|
|
|
// MSRoomGameWebVC.m
|
|
|
|
|
// YuMi
|
|
|
|
|
//
|
|
|
|
|
// Created by duoban on 2024/4/28.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#import "MSRoomGameWebVC.h"
|
2024-04-30 19:30:11 +08:00
|
|
|
|
#import "LittleGameInfoModel.h"
|
|
|
|
|
#import "RoomInfoModel.h"
|
|
|
|
|
#import "XPIAPRechargeViewController.h"
|
|
|
|
|
|
2024-04-28 11:41:57 +08:00
|
|
|
|
@interface MSWeakWebViewScriptMessageDelegate : NSObject<WKScriptMessageHandler>
|
|
|
|
|
|
|
|
|
|
//WKScriptMessageHandler 这个协议类专门用来处理JavaScript调用原生OC的方法
|
|
|
|
|
@property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;
|
|
|
|
|
|
|
|
|
|
- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
@implementation MSWeakWebViewScriptMessageDelegate
|
|
|
|
|
|
|
|
|
|
- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate {
|
|
|
|
|
self = [super init];
|
|
|
|
|
if (self) {
|
|
|
|
|
_scriptDelegate = scriptDelegate;
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//遵循WKScriptMessageHandler协议,必须实现如下方法,然后把方法向外传递
|
|
|
|
|
//通过接收JS传出消息的name进行捕捉的回调方法
|
|
|
|
|
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
|
|
|
|
|
|
|
|
|
|
if ([self.scriptDelegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
|
|
|
|
|
[self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
typedef NS_ENUM(NSInteger, MSGameType) {
|
|
|
|
|
MSGameTypeBaiShun, // 百顺游戏
|
|
|
|
|
MSGameTypeJoyPlay, // JoyPlay游戏
|
|
|
|
|
MSGameTypeCC // CC游戏
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-28 11:41:57 +08:00
|
|
|
|
NSString * const kMSGetConfig = @"getConfig";
|
|
|
|
|
NSString * const kMSDestroy = @"destroy";
|
|
|
|
|
NSString * const kMSGameRecharge = @"gameRecharge";
|
|
|
|
|
NSString * const kMSGameLoaded = @"gameLoaded";
|
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
NSString * const kJPRecharge = @"recharge";
|
|
|
|
|
NSString * const kJPClickRecharge = @"clickRecharge";
|
|
|
|
|
NSString * const kJPClose = @"newTppClose";
|
|
|
|
|
|
|
|
|
|
|
2024-04-28 11:41:57 +08:00
|
|
|
|
|
|
|
|
|
@interface MSRoomGameWebVC () <WKNavigationDelegate, WKScriptMessageHandler,WKUIDelegate>
|
2024-07-29 20:23:38 +08:00
|
|
|
|
@property (strong, nonatomic) WKWebView *webView;
|
2024-04-28 11:41:57 +08:00
|
|
|
|
@property (strong, nonatomic) UIProgressView *progressView;
|
|
|
|
|
@property (nonatomic, strong) WKUserContentController *ms_userContentController;
|
2024-04-30 19:30:11 +08:00
|
|
|
|
@property (nonatomic,weak) id<RoomHostDelegate> hostDelegate;
|
|
|
|
|
@property(nonatomic,strong) ActivityInfoModel *gameModel;
|
2024-05-07 19:40:21 +08:00
|
|
|
|
@property(nonatomic,strong) UIButton *backBtn;
|
2025-05-08 17:10:54 +08:00
|
|
|
|
@property (nonatomic, assign) MSGameType gameType;
|
2024-10-21 18:29:30 +08:00
|
|
|
|
@property (nonatomic, assign) BOOL isCharing;
|
2025-05-08 17:10:54 +08:00
|
|
|
|
@property (nonatomic, strong) NSURLRequest *lastRequest;
|
|
|
|
|
@property (nonatomic, assign) NSInteger retryCount;
|
|
|
|
|
@property (nonatomic, strong) NSTimer *loadingTimer;
|
2024-04-28 11:41:57 +08:00
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation MSRoomGameWebVC
|
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
- (void)dealloc {
|
|
|
|
|
[self cleanupWebView];
|
2025-05-21 18:59:32 +08:00
|
|
|
|
[self hideHUD];
|
2025-05-08 17:10:54 +08:00
|
|
|
|
[self.loadingTimer invalidate];
|
|
|
|
|
self.loadingTimer = nil;
|
|
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)cleanupWebView {
|
|
|
|
|
if (_webView) {
|
|
|
|
|
[_webView stopLoading];
|
|
|
|
|
_webView.navigationDelegate = nil;
|
|
|
|
|
_webView.UIDelegate = nil;
|
|
|
|
|
[_webView removeFromSuperview];
|
|
|
|
|
_webView = nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_ms_userContentController) {
|
|
|
|
|
[_ms_userContentController removeScriptMessageHandlerForName:kMSGetConfig];
|
|
|
|
|
[_ms_userContentController removeScriptMessageHandlerForName:kMSDestroy];
|
|
|
|
|
[_ms_userContentController removeScriptMessageHandlerForName:kMSGameRecharge];
|
|
|
|
|
[_ms_userContentController removeScriptMessageHandlerForName:kMSGameLoaded];
|
|
|
|
|
[_ms_userContentController removeScriptMessageHandlerForName:@"closeGame"];
|
|
|
|
|
[_ms_userContentController removeScriptMessageHandlerForName:@"pay"];
|
|
|
|
|
[_ms_userContentController removeScriptMessageHandlerForName:kJPClose];
|
|
|
|
|
[_ms_userContentController removeScriptMessageHandlerForName:kJPRecharge];
|
|
|
|
|
[_ms_userContentController removeScriptMessageHandlerForName:kJPClickRecharge];
|
|
|
|
|
_ms_userContentController = nil;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-30 19:30:11 +08:00
|
|
|
|
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate gameModel:(ActivityInfoModel *)gameModel
|
|
|
|
|
{
|
|
|
|
|
self = [super init];
|
|
|
|
|
if (self) {
|
|
|
|
|
self.hostDelegate = delegate;
|
|
|
|
|
self.gameModel = gameModel;
|
2025-05-08 17:10:54 +08:00
|
|
|
|
NSString *upperCode = gameModel.code.uppercaseString;
|
|
|
|
|
if ([upperCode isEqualToString:@"BAISHUN"]) {
|
|
|
|
|
self.gameType = MSGameTypeBaiShun;
|
|
|
|
|
} else if ([upperCode isEqualToString:@"JOYPLAY"]) {
|
|
|
|
|
self.gameType = MSGameTypeJoyPlay;
|
|
|
|
|
} else {
|
|
|
|
|
self.gameType = MSGameTypeCC;
|
|
|
|
|
}
|
2024-04-30 19:30:11 +08:00
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
- (BOOL)isHiddenNavBar {
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
2024-04-28 11:41:57 +08:00
|
|
|
|
- (void)viewDidLoad {
|
|
|
|
|
[super viewDidLoad];
|
|
|
|
|
[self installUI];
|
2024-06-10 16:10:15 +08:00
|
|
|
|
[self setupBackButton];
|
2025-05-08 17:10:54 +08:00
|
|
|
|
#if DEBUG
|
|
|
|
|
// [self setupLoadingTimer];
|
|
|
|
|
#endif
|
|
|
|
|
[self setupNotifications];
|
2024-08-02 21:09:02 +08:00
|
|
|
|
[self showLoading];
|
2024-06-10 16:10:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
- (void)setupLoadingTimer {
|
|
|
|
|
self.loadingTimer = [NSTimer scheduledTimerWithTimeInterval:15.0
|
|
|
|
|
target:self
|
|
|
|
|
selector:@selector(handleLoadingTimeout)
|
|
|
|
|
userInfo:nil
|
|
|
|
|
repeats:NO];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)setupNotifications {
|
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
|
selector:@selector(handleApplicationDidBecomeActive)
|
|
|
|
|
name:UIApplicationDidBecomeActiveNotification
|
|
|
|
|
object:nil];
|
|
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
|
selector:@selector(handleApplicationWillResignActive)
|
|
|
|
|
name:UIApplicationWillResignActiveNotification
|
|
|
|
|
object:nil];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)handleLoadingTimeout {
|
|
|
|
|
[self hideHUD];
|
|
|
|
|
[XNDJTDDLoadingTool showErrorWithMessage:@"加载超时,请检查网络后重试"];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)handleApplicationDidBecomeActive {
|
|
|
|
|
if (self.webView && !self.webView.isLoading) {
|
|
|
|
|
[self.webView reload];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)handleApplicationWillResignActive {
|
|
|
|
|
[self.webView evaluateJavaScript:@"if(typeof(onAppPause) === 'function') { onAppPause(); }" completionHandler:nil];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-10-21 18:29:30 +08:00
|
|
|
|
- (void)viewWillAppear:(BOOL)animated {
|
|
|
|
|
[super viewWillAppear:animated];
|
2025-05-08 17:10:54 +08:00
|
|
|
|
if (self.gameType != MSGameTypeBaiShun &&
|
2024-10-21 18:29:30 +08:00
|
|
|
|
self.isCharing) {
|
|
|
|
|
self.isCharing = NO;
|
|
|
|
|
[self updateCoin];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-10 16:10:15 +08:00
|
|
|
|
- (void)setupBackButton {
|
2025-05-08 17:10:54 +08:00
|
|
|
|
if (self.gameType == MSGameTypeJoyPlay && self.gameModel.showType == ActivityShowType_Full) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-05-07 19:40:21 +08:00
|
|
|
|
self.backBtn = [UIButton new];
|
|
|
|
|
[self.view addSubview:self.backBtn];
|
2024-10-21 18:29:30 +08:00
|
|
|
|
self.backBtn.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight);
|
2024-05-07 19:40:21 +08:00
|
|
|
|
[self.backBtn addTarget:self action:@selector(backBtnAction) forControlEvents:UIControlEventTouchUpInside];
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}
|
2024-06-10 16:10:15 +08:00
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
- (void)installUI {
|
2024-05-07 19:40:21 +08:00
|
|
|
|
self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.4];
|
2025-05-08 17:10:54 +08:00
|
|
|
|
[self setupWebViewConfiguration];
|
|
|
|
|
[self setupWebViewConfiguration];
|
|
|
|
|
[self loadGameContent];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)setupWebViewConfiguration {
|
2024-04-28 11:41:57 +08:00
|
|
|
|
MSWeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[MSWeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
|
|
|
|
|
_ms_userContentController = [[WKUserContentController alloc] init];
|
|
|
|
|
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kMSGetConfig];
|
|
|
|
|
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kMSDestroy];
|
|
|
|
|
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kMSGameRecharge];
|
|
|
|
|
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kMSGameLoaded];
|
2024-07-29 20:23:38 +08:00
|
|
|
|
|
2024-10-21 18:29:30 +08:00
|
|
|
|
/// LEADERCC
|
|
|
|
|
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:@"closeGame"];
|
|
|
|
|
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:@"pay"];
|
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
/// JOYPLAY
|
|
|
|
|
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate
|
|
|
|
|
name:kJPClose];
|
|
|
|
|
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate
|
|
|
|
|
name:kJPRecharge];
|
|
|
|
|
[_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate
|
|
|
|
|
name:kJPClickRecharge];
|
|
|
|
|
|
2024-04-28 11:41:57 +08:00
|
|
|
|
|
|
|
|
|
WKWebViewConfiguration *config = [WKWebViewConfiguration new];
|
|
|
|
|
config.allowsInlineMediaPlayback = YES;
|
2025-05-08 17:10:54 +08:00
|
|
|
|
config.mediaTypesRequiringUserActionForPlayback = NO;
|
2024-04-28 11:41:57 +08:00
|
|
|
|
[config setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];
|
|
|
|
|
//⾳视频的播放不需要⽤⼾⼿势触发, 即为⾃动播放
|
2024-10-21 18:29:30 +08:00
|
|
|
|
config.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
|
2024-04-28 11:41:57 +08:00
|
|
|
|
config.preferences = [[WKPreferences alloc]init];
|
|
|
|
|
WKPreferences *preferences = [WKPreferences new];
|
|
|
|
|
preferences.javaScriptCanOpenWindowsAutomatically = YES;
|
|
|
|
|
config.preferences = preferences;
|
|
|
|
|
config.preferences.javaScriptEnabled = YES;
|
|
|
|
|
config.userContentController = _ms_userContentController;
|
2024-04-30 19:30:11 +08:00
|
|
|
|
|
2024-10-21 18:29:30 +08:00
|
|
|
|
CGRect frame = CGRectZero;
|
2025-05-08 17:10:54 +08:00
|
|
|
|
if (self.gameType == MSGameTypeBaiShun) {
|
2024-10-21 18:29:30 +08:00
|
|
|
|
frame = CGRectMake(0,0,
|
|
|
|
|
KScreenWidth, KScreenHeight);
|
|
|
|
|
} else {
|
|
|
|
|
if(self.gameModel.showType == ActivityShowType_Half){
|
|
|
|
|
frame = CGRectMake(0, KScreenHeight * 0.3,
|
|
|
|
|
KScreenWidth, KScreenHeight * 0.7);
|
|
|
|
|
} else {
|
|
|
|
|
frame = CGRectMake(0,0,
|
|
|
|
|
KScreenWidth, KScreenHeight);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.webView = [[WKWebView alloc] initWithFrame:frame
|
|
|
|
|
configuration:config];
|
2024-07-29 20:23:38 +08:00
|
|
|
|
[self.webView.scrollView setBackgroundColor:[UIColor clearColor]];
|
|
|
|
|
[self.webView setBackgroundColor:[UIColor clearColor]];
|
|
|
|
|
[self.webView setUIDelegate:self];
|
|
|
|
|
self.webView.navigationDelegate = self;
|
2024-04-28 11:41:57 +08:00
|
|
|
|
//设置⽹⻚透明
|
2024-07-29 20:23:38 +08:00
|
|
|
|
[self.webView setOpaque:NO];
|
2024-04-28 11:41:57 +08:00
|
|
|
|
//设置⽹⻚全屏
|
|
|
|
|
if (@available(iOS 11.0, *)) {
|
2024-10-21 18:29:30 +08:00
|
|
|
|
self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}
|
2024-07-29 20:23:38 +08:00
|
|
|
|
[self.view addSubview:self.webView];
|
2025-05-08 17:10:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)loadGameContent {
|
2024-04-30 19:30:11 +08:00
|
|
|
|
NSString *h5Url = self.gameModel.skipContent;
|
2024-10-21 18:29:30 +08:00
|
|
|
|
NSURL *url = [self handleGameURL:h5Url];
|
2025-05-08 17:10:54 +08:00
|
|
|
|
|
|
|
|
|
if (!url) {
|
|
|
|
|
[self hideHUD];
|
|
|
|
|
[XNDJTDDLoadingTool showErrorWithMessage:@"游戏链接无效"];
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url
|
|
|
|
|
cachePolicy:NSURLRequestUseProtocolCachePolicy
|
|
|
|
|
timeoutInterval:15.0];
|
|
|
|
|
self.lastRequest = request;
|
2024-07-29 20:23:38 +08:00
|
|
|
|
[self.webView loadRequest:request];
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
- (BOOL)isValidGameURL:(NSString *)urlString {
|
2025-05-21 18:59:32 +08:00
|
|
|
|
if ([NSString isEmpty:urlString]) {
|
2025-05-08 17:10:54 +08:00
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
|
|
|
return (url && url.scheme && url.host);
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-21 18:29:30 +08:00
|
|
|
|
- (NSURL *)handleGameURL:(NSString *)url {
|
2025-05-08 17:10:54 +08:00
|
|
|
|
if (![self isValidGameURL:url]) {
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
2025-07-15 14:35:05 +08:00
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
switch (self.gameType) {
|
|
|
|
|
case MSGameTypeBaiShun:
|
2025-07-15 14:35:05 +08:00
|
|
|
|
url = [self addSupportLanguage:url];
|
2025-05-08 17:10:54 +08:00
|
|
|
|
return [NSURL URLWithString:url];
|
|
|
|
|
case MSGameTypeJoyPlay:
|
|
|
|
|
url = [url stringByAppendingFormat:@"?gameId=%@", @(self.gameModel.gameModel.gameId)];
|
|
|
|
|
url = [url stringByAppendingFormat:@"&appKey=%@",
|
|
|
|
|
self.gameModel.gameModel.appKey];
|
|
|
|
|
url = [url stringByAppendingFormat:@"&mini=%@", @(self.gameModel.showType == ActivityShowType_Half ? 1 : 0)];
|
|
|
|
|
if (self.gameModel.showType == ActivityShowType_Full) {
|
|
|
|
|
url = [url stringByAppendingFormat:@"&safeTop=1"];
|
|
|
|
|
}
|
2025-05-23 14:43:39 +08:00
|
|
|
|
url = [url stringByAppendingFormat:@"&roomId=%ld",
|
|
|
|
|
(long)self.hostDelegate.getRoomInfo.uid];
|
2025-05-08 17:10:54 +08:00
|
|
|
|
break;
|
|
|
|
|
case MSGameTypeCC:
|
2025-05-23 14:43:39 +08:00
|
|
|
|
url = [url stringByAppendingFormat:@"&roomid=%ld",
|
|
|
|
|
(long)self.hostDelegate.getRoomInfo.uid];
|
|
|
|
|
break;
|
2025-05-08 17:10:54 +08:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 14:35:05 +08:00
|
|
|
|
url = [self addSupportLanguage:url];
|
|
|
|
|
|
2025-05-23 14:43:39 +08:00
|
|
|
|
if (![NSString isEmpty:self.gameModel.gameModel.urlParam]) {
|
|
|
|
|
url = [url stringByAppendingString:[NSString stringWithFormat:@"&%@", self.gameModel.gameModel.urlParam]];
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
url = [url stringByAppendingFormat:@"&token=%@", self.gameModel.gameModel.code];
|
|
|
|
|
url = [url stringByAppendingFormat:@"&uid=%@", [AccountInfoStorage instance].getUid];
|
2025-05-23 14:43:39 +08:00
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
return [NSURL URLWithString:url];
|
2024-10-21 18:29:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-07-15 14:35:05 +08:00
|
|
|
|
- (NSString *)addSupportLanguage:(NSString *)url {
|
|
|
|
|
NSString *mark = @"&";
|
|
|
|
|
NSString *lang = @"en-US";
|
|
|
|
|
if (![url containsString:@"?"]) {
|
|
|
|
|
mark = @"?";
|
|
|
|
|
}
|
|
|
|
|
if (isMSTR()) {
|
|
|
|
|
lang = @"tr-TR";
|
|
|
|
|
} else if (isMSZH()) {
|
|
|
|
|
lang = @"zh-TW";
|
|
|
|
|
} else if (isMSRTL()) {
|
|
|
|
|
lang = @"ar-EG";
|
|
|
|
|
} else if (isMSPT()) {
|
|
|
|
|
lang = @"pt-BR";
|
2025-09-15 17:35:16 +08:00
|
|
|
|
} else if (isMSES()) {
|
2025-09-15 18:35:29 +08:00
|
|
|
|
lang = @"es-ES";
|
2025-07-15 14:35:05 +08:00
|
|
|
|
}
|
|
|
|
|
url = [url stringByAppendingFormat:@"%@lang=%@", mark, lang];
|
|
|
|
|
return url;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-29 20:23:38 +08:00
|
|
|
|
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
|
2024-08-02 21:09:02 +08:00
|
|
|
|
[self hideHUD];
|
2025-05-08 17:10:54 +08:00
|
|
|
|
self.retryCount = 0;
|
|
|
|
|
[self.loadingTimer invalidate];
|
|
|
|
|
self.loadingTimer = nil;
|
|
|
|
|
|
|
|
|
|
if (self.gameType != MSGameTypeBaiShun) {
|
2024-10-21 18:29:30 +08:00
|
|
|
|
self.backBtn.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight*0.3);
|
|
|
|
|
}
|
2025-05-08 17:10:54 +08:00
|
|
|
|
|
|
|
|
|
// 注入错误处理脚本
|
|
|
|
|
NSString *errorHandler = @"window.onerror = function(msg, url, line, col, error) { window.webkit.messageHandlers.error.postMessage({message: msg, url: url, line: line, col: col}); return false; }";
|
|
|
|
|
[webView evaluateJavaScript:errorHandler completionHandler:nil];
|
2024-10-21 18:29:30 +08:00
|
|
|
|
|
2024-07-29 20:23:38 +08:00
|
|
|
|
#if DEBUG
|
|
|
|
|
NSString *fileName = @"vconsole.min.js"; // 你要查找的文件名
|
|
|
|
|
NSString *directory = [[NSBundle mainBundle] resourcePath];
|
|
|
|
|
|
|
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
|
NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtPath:directory];
|
|
|
|
|
NSString *filePath;
|
|
|
|
|
|
|
|
|
|
for (NSString *path in enumerator) {
|
|
|
|
|
if ([[path lastPathComponent] containsString:fileName]) {
|
|
|
|
|
filePath = [directory stringByAppendingPathComponent:path];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (filePath.length > 0) {
|
|
|
|
|
NSString *vConsoleScript = [NSString stringWithContentsOfFile:filePath
|
|
|
|
|
encoding:NSUTF8StringEncoding error:nil];
|
|
|
|
|
[self.webView evaluateJavaScript:vConsoleScript completionHandler:nil];
|
|
|
|
|
|
|
|
|
|
// 初始化 vConsole
|
|
|
|
|
NSString *initVConsoleScript = @"var vConsole = new VConsole();";
|
|
|
|
|
[self.webView evaluateJavaScript:initVConsoleScript completionHandler:nil];
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-08 17:10:54 +08:00
|
|
|
|
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
|
|
|
|
|
[self handleWebViewError:error];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
|
|
|
|
|
[self handleWebViewError:error];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)handleWebViewError:(NSError *)error {
|
|
|
|
|
if (self.retryCount < 3) {
|
|
|
|
|
self.retryCount++;
|
|
|
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
|
|
[self.webView loadRequest:self.lastRequest];
|
2024-04-28 11:41:57 +08:00
|
|
|
|
});
|
2025-05-08 17:10:54 +08:00
|
|
|
|
} else {
|
|
|
|
|
[self hideHUD];
|
|
|
|
|
[XNDJTDDLoadingTool showErrorWithMessage:@"网络连接失败,请稍后重试"];
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
|
|
|
|
|
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
|
|
|
|
|
NSURLCredential *card = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
|
|
|
|
|
completionHandler(NSURLSessionAuthChallengeUseCredential, card);
|
|
|
|
|
} else {
|
|
|
|
|
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 调⽤JS
|
|
|
|
|
- (void)callJs:(NSString*)method withJavaScriptValue:(nullable id)arguments
|
|
|
|
|
{
|
2024-07-29 20:23:38 +08:00
|
|
|
|
@kWeakify(self);
|
2024-04-28 11:41:57 +08:00
|
|
|
|
if (arguments) {
|
|
|
|
|
NSData *data = [NSJSONSerialization dataWithJSONObject:arguments
|
|
|
|
|
options:(NSJSONWritingPrettyPrinted) error:nil];
|
|
|
|
|
NSString *jsonStr = [[NSString alloc] initWithData:data
|
|
|
|
|
encoding:NSUTF8StringEncoding];
|
|
|
|
|
NSString *jsMethods = [NSString stringWithFormat:@"%@(%@)", method,
|
|
|
|
|
jsonStr];
|
2024-07-29 20:23:38 +08:00
|
|
|
|
[self.webView evaluateJavaScript:jsMethods completionHandler:^(id
|
2024-04-28 11:41:57 +08:00
|
|
|
|
_Nullable resp, NSError * _Nullable error) {
|
2024-07-29 20:23:38 +08:00
|
|
|
|
@kStrongify(self);
|
2025-04-10 18:01:01 +08:00
|
|
|
|
NSLog(@"error = %@ , response = %@",error, resp);
|
2024-06-10 16:10:15 +08:00
|
|
|
|
[self.backBtn removeFromSuperview];
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}];
|
|
|
|
|
} else {
|
|
|
|
|
NSString *jsMethods = [NSString stringWithFormat:@"%@({})", method];
|
2024-07-29 20:23:38 +08:00
|
|
|
|
[self.webView evaluateJavaScript:jsMethods completionHandler:^(id
|
2024-04-28 11:41:57 +08:00
|
|
|
|
_Nullable resp, NSError * _Nullable error) {
|
2024-07-29 20:23:38 +08:00
|
|
|
|
@kStrongify(self);
|
2025-04-10 18:01:01 +08:00
|
|
|
|
NSLog(@"error = %@ , response = %@",error, resp);
|
2024-06-10 16:10:15 +08:00
|
|
|
|
[self.backBtn removeFromSuperview];
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
- (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString
|
|
|
|
|
{
|
|
|
|
|
if (jsonString == nil && jsonString.length == 0) {
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
|
NSError *err;
|
|
|
|
|
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
|
|
|
|
|
options:NSJSONReadingMutableContainers
|
|
|
|
|
error:&err];
|
|
|
|
|
if(err)
|
|
|
|
|
{
|
2025-04-10 18:01:01 +08:00
|
|
|
|
NSLog(@"json解析失败:%@",err);
|
2024-04-28 11:41:57 +08:00
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
return dic;
|
|
|
|
|
}
|
|
|
|
|
// 绑定协议⽅法
|
2024-10-21 18:29:30 +08:00
|
|
|
|
- (void)userContentController:(WKUserContentController *)userContentController
|
2024-04-28 11:41:57 +08:00
|
|
|
|
didReceiveScriptMessage:(WKScriptMessage *)message
|
|
|
|
|
{
|
2024-10-21 18:29:30 +08:00
|
|
|
|
/// BaiShun
|
2025-05-08 17:10:54 +08:00
|
|
|
|
switch (self.gameType) {
|
|
|
|
|
case MSGameTypeBaiShun: {
|
|
|
|
|
NSDictionary *dicBody = [self dictionaryWithJsonString:message.body];
|
|
|
|
|
if ([message.name isEqualToString:kMSGetConfig]) {
|
|
|
|
|
[self getConfig:dicBody];
|
|
|
|
|
} else if ([message.name isEqualToString:kMSDestroy]) {
|
|
|
|
|
[self destroy:dicBody];
|
|
|
|
|
} else if ([message.name isEqualToString:kMSGameLoaded]) {
|
|
|
|
|
[self gameLoaded:dicBody];
|
|
|
|
|
} else if ([message.name isEqualToString:kMSGameRecharge]) {
|
|
|
|
|
[self gameRecharge:dicBody];
|
|
|
|
|
} else {
|
|
|
|
|
NSLog(@"未实现⽅法 : %@ --> %@", message.name, message.body);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2024-10-21 18:29:30 +08:00
|
|
|
|
}
|
2025-05-08 17:10:54 +08:00
|
|
|
|
case MSGameTypeJoyPlay: {
|
|
|
|
|
if ([message.name isEqualToString:kJPRecharge]) {
|
|
|
|
|
XPIAPRechargeViewController * webVC =[[XPIAPRechargeViewController alloc] init];
|
|
|
|
|
webVC.type = @"4";
|
|
|
|
|
[self.navigationController pushViewController:webVC animated:YES];
|
|
|
|
|
self.isCharing = YES;
|
|
|
|
|
} else if ([message.name isEqualToString:kJPClickRecharge]) {
|
|
|
|
|
[self gameRecharge:@{}];
|
|
|
|
|
} else if ([message.name isEqualToString:kJPClose]) {
|
|
|
|
|
[self backBtnAction];
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case MSGameTypeCC: {
|
|
|
|
|
/// LeaderCC
|
|
|
|
|
NSString* method = [NSString stringWithFormat:@"%@:", message.name];
|
|
|
|
|
SEL selector = NSSelectorFromString(method);
|
|
|
|
|
if([self respondsToSelector:selector]){
|
|
|
|
|
[self performSelector:selector withObject:message.body];
|
|
|
|
|
}else{
|
|
|
|
|
NSLog(@"未實現方法 : %@ --> %@", message.name, message.body);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2024-10-21 18:29:30 +08:00
|
|
|
|
}
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-21 18:29:30 +08:00
|
|
|
|
|
|
|
|
|
#pragma mark - LeaderCC Delegate
|
|
|
|
|
// 关闭游戏
|
|
|
|
|
- (void)closeGame:(NSDictionary*)args {
|
2024-10-22 14:34:42 +08:00
|
|
|
|
[self backBtnAction];
|
2024-10-21 18:29:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示充值界面
|
|
|
|
|
- (void)pay:(NSDictionary*)args {
|
|
|
|
|
//拉起充值商城 TODO 客⼾端
|
|
|
|
|
TTAlertConfig *config = [[TTAlertConfig alloc]init];
|
2025-04-10 18:01:01 +08:00
|
|
|
|
config.title = YMLocalizedString(@"UserDetail_CP_Toast_0");
|
2024-10-21 18:29:30 +08:00
|
|
|
|
config.message = YMLocalizedString(@"XPNobleCenterViewController3");
|
|
|
|
|
config.actionStyle = TTAlertActionBothStyle;
|
|
|
|
|
@kWeakify(self);
|
|
|
|
|
[TTPopup alertWithConfig:config showBorder:NO confirmHandler:^{
|
|
|
|
|
@kStrongify(self);
|
|
|
|
|
XPIAPRechargeViewController * webVC =[[XPIAPRechargeViewController alloc] init];
|
|
|
|
|
webVC.type = @"4";
|
|
|
|
|
[self.navigationController pushViewController:webVC animated:YES];
|
|
|
|
|
self.isCharing = YES;
|
|
|
|
|
} cancelHandler:^{
|
|
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)updateCoin {
|
|
|
|
|
// 平时游戏币更新不需要调用该方法,以防止影响游戏开奖动画。
|
|
|
|
|
[self.webView evaluateJavaScript:@"updateCoin()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
|
|
|
|
|
if (error) {
|
2025-04-10 18:01:01 +08:00
|
|
|
|
NSLog(@"Error calling JS function: %@", error.localizedDescription);
|
2024-10-21 18:29:30 +08:00
|
|
|
|
} else {
|
2025-04-10 18:01:01 +08:00
|
|
|
|
NSLog(@"JS function called successfully, result: %@", result);
|
2024-10-21 18:29:30 +08:00
|
|
|
|
}
|
|
|
|
|
}];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - BaiShun Delegate
|
2024-04-28 11:41:57 +08:00
|
|
|
|
// 获取信息配置
|
|
|
|
|
- (void) getConfig:(NSDictionary*)args
|
|
|
|
|
{
|
2025-04-10 18:01:01 +08:00
|
|
|
|
NSLog(@"BSGAME %s","游戏调⽤getConfig");
|
2024-04-28 11:41:57 +08:00
|
|
|
|
NSString* method = [args objectForKey:@"jsCallback"];
|
2024-04-30 19:30:11 +08:00
|
|
|
|
RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo;
|
|
|
|
|
ActivityInfoItemModel *gameModel = self.gameModel.gameModel;
|
|
|
|
|
NSString *appChannel = gameModel.appChannel ?: @"";
|
|
|
|
|
int64_t appId = gameModel.appId;
|
|
|
|
|
NSString *userId = [AccountInfoStorage instance].getUid;
|
|
|
|
|
NSString *code = gameModel.code ?: @"";
|
|
|
|
|
NSString *roomId = [NSString stringWithFormat:@"%ld",roomInfo.uid];
|
|
|
|
|
NSString *gameMode = gameModel.gameMode ?: @"";
|
|
|
|
|
NSDictionary *gameConfig = gameModel.gameConfig ?: @{};
|
|
|
|
|
int gsp = gameModel.gsp;
|
2024-04-28 11:41:57 +08:00
|
|
|
|
// 数据只是参考值,需要根据⾃⼰APP进⾏赋值
|
|
|
|
|
NSObject* configData = @{
|
2024-04-30 19:30:11 +08:00
|
|
|
|
@"appChannel":appChannel,
|
|
|
|
|
@"appId":@(appId),
|
|
|
|
|
@"userId":userId,
|
|
|
|
|
@"code":code,
|
|
|
|
|
@"roomId":roomId,
|
|
|
|
|
@"gameMode":gameMode,
|
|
|
|
|
@"language":[self getlanguage],
|
|
|
|
|
@"gameConfig":gameConfig,
|
|
|
|
|
@"gsp":@(gsp),
|
2024-04-28 11:41:57 +08:00
|
|
|
|
};
|
|
|
|
|
[self callJs:method withJavaScriptValue:configData];
|
|
|
|
|
}
|
2024-04-30 19:30:11 +08:00
|
|
|
|
-(NSString *)getlanguage{
|
|
|
|
|
NSString *language = [NSBundle getLanguageText];
|
|
|
|
|
if ([language hasPrefix:@"zh"]) {
|
|
|
|
|
if ([language rangeOfString:@"Hans"].location != NSNotFound) {
|
|
|
|
|
language = @"0"; // 简体中文
|
|
|
|
|
} else {
|
|
|
|
|
language = @"1"; // 繁體中文
|
|
|
|
|
}
|
|
|
|
|
}else if([language hasPrefix:@"ar"]){///阿拉伯语
|
|
|
|
|
language = @"7";
|
|
|
|
|
}else{///英文
|
|
|
|
|
language = @"2";
|
|
|
|
|
}
|
|
|
|
|
return language;
|
|
|
|
|
}
|
2024-04-28 11:41:57 +08:00
|
|
|
|
// 销毁游戏
|
|
|
|
|
- (void) destroy:(NSDictionary*)args
|
|
|
|
|
{
|
2025-04-10 18:01:01 +08:00
|
|
|
|
NSLog(@"BSGAME %s","游戏调⽤destroy");
|
2024-04-28 11:41:57 +08:00
|
|
|
|
//关闭游戏 TODO 客⼾端
|
2024-04-30 19:30:11 +08:00
|
|
|
|
[self willMoveToParentViewController:nil]; //1
|
|
|
|
|
[self.view removeFromSuperview]; //2
|
|
|
|
|
[self removeFromParentViewController]; //3
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}
|
2024-05-07 19:40:21 +08:00
|
|
|
|
-(void)backBtnAction{
|
|
|
|
|
TTAlertConfig *config = [[TTAlertConfig alloc]init];
|
2025-04-10 18:01:01 +08:00
|
|
|
|
config.title = YMLocalizedString(@"UserDetail_CP_Toast_0");
|
2024-05-07 19:40:21 +08:00
|
|
|
|
config.message = YMLocalizedString(@"MSRoomGameWebVC0");
|
|
|
|
|
config.actionStyle = TTAlertActionBothStyle;
|
2024-10-22 14:34:42 +08:00
|
|
|
|
@kWeakify(self);
|
2024-05-07 19:40:21 +08:00
|
|
|
|
[TTPopup alertWithConfig:config showBorder:NO confirmHandler:^{
|
2024-10-22 14:34:42 +08:00
|
|
|
|
@kStrongify(self);
|
|
|
|
|
[self destroy:nil];
|
2024-05-07 19:40:21 +08:00
|
|
|
|
} cancelHandler:^{
|
|
|
|
|
}];
|
|
|
|
|
}
|
2024-04-28 11:41:57 +08:00
|
|
|
|
// 提⽰余额不⾜
|
|
|
|
|
- (void) gameRecharge:(NSDictionary*)args
|
|
|
|
|
{
|
2025-04-10 18:01:01 +08:00
|
|
|
|
NSLog(@"BSGAME %s","游戏调⽤gameRecharge");
|
2024-04-28 11:41:57 +08:00
|
|
|
|
//拉起充值商城 TODO 客⼾端
|
2024-04-30 19:30:11 +08:00
|
|
|
|
TTAlertConfig *config = [[TTAlertConfig alloc]init];
|
2025-04-10 18:01:01 +08:00
|
|
|
|
config.title = YMLocalizedString(@"UserDetail_CP_Toast_0");
|
2024-04-30 19:30:11 +08:00
|
|
|
|
config.message = YMLocalizedString(@"XPNobleCenterViewController3");
|
|
|
|
|
config.actionStyle = TTAlertActionBothStyle;
|
2024-10-21 18:29:30 +08:00
|
|
|
|
@kWeakify(self);
|
2024-04-30 19:30:11 +08:00
|
|
|
|
[TTPopup alertWithConfig:config showBorder:NO confirmHandler:^{
|
2024-10-21 18:29:30 +08:00
|
|
|
|
@kStrongify(self);
|
2024-04-30 19:30:11 +08:00
|
|
|
|
XPIAPRechargeViewController * webVC =[[XPIAPRechargeViewController alloc] init];
|
|
|
|
|
webVC.type = @"4";
|
|
|
|
|
[self.navigationController pushViewController:webVC animated:YES];
|
2024-10-21 18:29:30 +08:00
|
|
|
|
self.isCharing = YES;
|
2024-04-30 19:30:11 +08:00
|
|
|
|
} cancelHandler:^{
|
|
|
|
|
|
|
|
|
|
}];
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}
|
|
|
|
|
// 游戏加载完毕
|
|
|
|
|
- (void) gameLoaded:(NSDictionary*)args
|
|
|
|
|
{
|
|
|
|
|
// 游戏加载完毕 TODO 客⼾端
|
2024-05-07 19:40:21 +08:00
|
|
|
|
[self.backBtn removeFromSuperview];
|
2024-04-28 11:41:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|